devices/e1000e/netdev-3.10-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2585 26480934a057
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.
2585
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2013 Intel Corporation.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/module.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/types.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/init.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/pci.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/vmalloc.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/pagemap.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/delay.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/netdevice.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <linux/interrupt.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <linux/tcp.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <linux/ipv6.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <linux/slab.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <net/checksum.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <net/ip6_checksum.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <linux/ethtool.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
#include <linux/if_vlan.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include <linux/cpu.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
#include <linux/smp.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#include <linux/pm_qos.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
#include <linux/pm_runtime.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#include <linux/aer.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
#include <linux/prefetch.h>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
#include "e1000.h"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
#define DRV_EXTRAVERSION "-k"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
#define DRV_VERSION "2.3.2" DRV_EXTRAVERSION
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
char e1000e_driver_name[] = "e1000e";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
const char e1000e_driver_version[] = DRV_VERSION;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
static int debug = -1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
module_param(debug, int, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
static const struct e1000_info *e1000_info_tbl[] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	[board_82571]		= &e1000_82571_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	[board_82572]		= &e1000_82572_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	[board_82573]		= &e1000_82573_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	[board_82574]		= &e1000_82574_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	[board_82583]		= &e1000_82583_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	[board_80003es2lan]	= &e1000_es2_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	[board_ich8lan]		= &e1000_ich8_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	[board_ich9lan]		= &e1000_ich9_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	[board_ich10lan]	= &e1000_ich10_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	[board_pchlan]		= &e1000_pch_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	[board_pch2lan]		= &e1000_pch2_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	[board_pch_lpt]		= &e1000_pch_lpt_info,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
struct e1000_reg_info {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	u32 ofs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	char *name;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
static const struct e1000_reg_info e1000_reg_info_tbl[] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	/* General Registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	{E1000_CTRL, "CTRL"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	{E1000_STATUS, "STATUS"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	{E1000_CTRL_EXT, "CTRL_EXT"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	/* Interrupt Registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	{E1000_ICR, "ICR"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	/* Rx Registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	{E1000_RCTL, "RCTL"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	{E1000_RDLEN(0), "RDLEN"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	{E1000_RDH(0), "RDH"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	{E1000_RDT(0), "RDT"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	{E1000_RDTR, "RDTR"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	{E1000_RXDCTL(0), "RXDCTL"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	{E1000_ERT, "ERT"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	{E1000_RDBAL(0), "RDBAL"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	{E1000_RDBAH(0), "RDBAH"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	{E1000_RDFH, "RDFH"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	{E1000_RDFT, "RDFT"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	{E1000_RDFHS, "RDFHS"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	{E1000_RDFTS, "RDFTS"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	{E1000_RDFPC, "RDFPC"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	/* Tx Registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	{E1000_TCTL, "TCTL"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	{E1000_TDBAL(0), "TDBAL"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	{E1000_TDBAH(0), "TDBAH"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	{E1000_TDLEN(0), "TDLEN"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	{E1000_TDH(0), "TDH"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	{E1000_TDT(0), "TDT"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	{E1000_TIDV, "TIDV"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	{E1000_TXDCTL(0), "TXDCTL"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	{E1000_TADV, "TADV"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	{E1000_TARC(0), "TARC"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	{E1000_TDFH, "TDFH"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	{E1000_TDFT, "TDFT"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	{E1000_TDFHS, "TDFHS"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
	{E1000_TDFTS, "TDFTS"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	{E1000_TDFPC, "TDFPC"},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	/* List Terminator */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	{0, NULL}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
 * e1000_regdump - register printout routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
 * @hw: pointer to the HW structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
 * @reginfo: pointer to the register info table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	int n = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	char rname[16];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
	u32 regs[8];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
	switch (reginfo->ofs) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
	case E1000_RXDCTL(0):
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
		for (n = 0; n < 2; n++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
			regs[n] = __er32(hw, E1000_RXDCTL(n));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
	case E1000_TXDCTL(0):
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
		for (n = 0; n < 2; n++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
			regs[n] = __er32(hw, E1000_TXDCTL(n));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	case E1000_TARC(0):
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
		for (n = 0; n < 2; n++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
			regs[n] = __er32(hw, E1000_TARC(n));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
		pr_info("%-15s %08x\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
			reginfo->name, __er32(hw, reginfo->ofs));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
	snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
	pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
static void e1000e_dump_ps_pages(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
				 struct e1000_buffer *bi)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
	struct e1000_ps_page *ps_page;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
	for (i = 0; i < adapter->rx_ps_pages; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
		ps_page = &bi->ps_pages[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
		if (ps_page->page) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
			pr_info("packet dump for ps_page %d:\n", i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
				       16, 1, page_address(ps_page->page),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
				       PAGE_SIZE, true);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
 * e1000e_dump - Print registers, Tx-ring and Rx-ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
static void e1000e_dump(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	struct e1000_reg_info *reginfo;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	struct e1000_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	struct e1000_tx_desc *tx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	struct my_u0 {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		__le64 a;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		__le64 b;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	} *u0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	struct e1000_ring *rx_ring = adapter->rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	union e1000_rx_desc_packet_split *rx_desc_ps;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	union e1000_rx_desc_extended *rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	struct my_u1 {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
		__le64 a;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
		__le64 b;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
		__le64 c;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
		__le64 d;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	} *u1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	u32 staterr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	int i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	if (!netif_msg_hw(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	/* Print netdevice Info */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	if (netdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
		dev_info(&adapter->pdev->dev, "Net device Info\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
		pr_info("Device Name     state            trans_start      last_rx\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
		pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
			netdev->state, netdev->trans_start, netdev->last_rx);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	/* Print Registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	dev_info(&adapter->pdev->dev, "Register Dump\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	pr_info(" Register Name   Value\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	     reginfo->name; reginfo++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
		e1000_regdump(hw, reginfo);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	/* Print Tx Ring Summary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
	if (!netdev || !netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	dev_info(&adapter->pdev->dev, "Tx Ring Summary\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
		0, tx_ring->next_to_use, tx_ring->next_to_clean,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
		(unsigned long long)buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
		buffer_info->length,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
		buffer_info->next_to_watch,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
		(unsigned long long)buffer_info->time_stamp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	/* Print Tx Ring */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	if (!netif_msg_tx_done(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
		goto rx_ring_summary;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	dev_info(&adapter->pdev->dev, "Tx Ring Dump\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	 * Legacy Transmit Descriptor
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	 *   +--------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	 *   +--------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	 *   +--------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	 *   63       48 47        36 35    32 31     24 23    16 15        0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	 *   63      48 47    40 39       32 31             16 15    8 7      0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	 * Extended Data Descriptor (DTYP=0x1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	 * 0 |                     Buffer Address [63:0]                      |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	 *   +----------------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	pr_info("Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Legacy format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Context format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Data format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		const char *next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		tx_desc = E1000_TX_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
		u0 = (struct my_u0 *)tx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
			next_desc = " NTC/U";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
		else if (i == tx_ring->next_to_use)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
			next_desc = " NTU";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
		else if (i == tx_ring->next_to_clean)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
			next_desc = " NTC";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
			next_desc = "";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p%s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
			(!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
			 ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
			i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
			(unsigned long long)le64_to_cpu(u0->a),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
			(unsigned long long)le64_to_cpu(u0->b),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
			(unsigned long long)buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
			buffer_info->length, buffer_info->next_to_watch,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
			(unsigned long long)buffer_info->time_stamp,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
			buffer_info->skb, next_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		if (netif_msg_pktdata(adapter) && buffer_info->skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
				       16, 1, buffer_info->skb->data,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
				       buffer_info->skb->len, true);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	/* Print Rx Ring Summary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
rx_ring_summary:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	dev_info(&adapter->pdev->dev, "Rx Ring Summary\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	pr_info("Queue [NTU] [NTC]\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	pr_info(" %5d %5X %5X\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		0, rx_ring->next_to_use, rx_ring->next_to_clean);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	/* Print Rx Ring */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	if (!netif_msg_rx_status(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	dev_info(&adapter->pdev->dev, "Rx Ring Dump\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	switch (adapter->rx_ps_pages) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	case 1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
	case 2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
	case 3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
		/* [Extended] Packet Split Receive Descriptor Format
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		 *    +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		 *  0 |                Buffer Address 0 [63:0]              |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		 *    +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
		 *  8 |                Buffer Address 1 [63:0]              |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		 *    +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		 * 16 |                Buffer Address 2 [63:0]              |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		 *    +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		 * 24 |                Buffer Address 3 [63:0]              |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		 *    +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		pr_info("R  [desc]      [buffer 0 63:0 ] [buffer 1 63:0 ] [buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma       ] [bi->skb] <-- Ext Pkt Split format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		/* [Extended] Receive Descriptor (Write-Back) Format
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		 *   63       48 47    32 31     13 12    8 7    4 3        0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		 *   +------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		 * 0 | Packet   | IP     |  Rsvd   | MRQ   | Rsvd | MRQ RSS |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
		 *   | Checksum | Ident  |         | Queue |      |  Type   |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		 *   +------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
		 *   +------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		 *   63       48 47    32 31            20 19               0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
		pr_info("RWB[desc]      [ck ipid mrqhsh] [vl   l0 ee  es] [ l3  l2  l1 hs] [reserved      ] ---------------- [bi->skb] <-- Ext Rx Write-Back format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
		for (i = 0; i < rx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
			const char *next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
			buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
			rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
			u1 = (struct my_u1 *)rx_desc_ps;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
			staterr =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
			    le32_to_cpu(rx_desc_ps->wb.middle.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
			if (i == rx_ring->next_to_use)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
				next_desc = " NTU";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
			else if (i == rx_ring->next_to_clean)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
				next_desc = " NTC";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
				next_desc = "";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
			if (staterr & E1000_RXD_STAT_DD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
				/* Descriptor Done */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX ---------------- %p%s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
					"RWB", i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
					(unsigned long long)le64_to_cpu(u1->a),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
					(unsigned long long)le64_to_cpu(u1->b),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
					(unsigned long long)le64_to_cpu(u1->c),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
					(unsigned long long)le64_to_cpu(u1->d),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
					buffer_info->skb, next_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX %016llX %p%s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
					"R  ", i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
					(unsigned long long)le64_to_cpu(u1->a),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
					(unsigned long long)le64_to_cpu(u1->b),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
					(unsigned long long)le64_to_cpu(u1->c),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
					(unsigned long long)le64_to_cpu(u1->d),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
					(unsigned long long)buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
					buffer_info->skb, next_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
				if (netif_msg_pktdata(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
					e1000e_dump_ps_pages(adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
							     buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	case 0:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		/* Extended Receive Descriptor (Read) Format
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
		 *   +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
		 * 0 |                Buffer Address [63:0]                |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
		 *   +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
		 * 8 |                      Reserved                       |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		 *   +-----------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
		pr_info("R  [desc]      [buf addr 63:0 ] [reserved 63:0 ] [bi->dma       ] [bi->skb] <-- Ext (Read) format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
		/* Extended Receive Descriptor (Write-Back) Format
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
		 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		 *   63       48 47    32 31    24 23            4 3        0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		 *   +------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
		 *   |     RSS Hash      |        |               |         |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
		 * 0 +-------------------+  Rsvd  |   Reserved    | MRQ RSS |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
		 *   | Packet   | IP     |        |               |  Type   |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
		 *   | Checksum | Ident  |        |               |         |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
		 *   +------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
		 *   +------------------------------------------------------+
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
		 *   63       48 47    32 31            20 19               0
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
		pr_info("RWB[desc]      [cs ipid    mrq] [vt   ln xe  xs] [bi->skb] <-- Ext (Write-Back) format\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
		for (i = 0; i < rx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
			const char *next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
			buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
			rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
			u1 = (struct my_u1 *)rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
			if (i == rx_ring->next_to_use)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
				next_desc = " NTU";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
			else if (i == rx_ring->next_to_clean)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
				next_desc = " NTC";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
				next_desc = "";
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
			if (staterr & E1000_RXD_STAT_DD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
				/* Descriptor Done */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
				pr_info("%s[0x%03X]     %016llX %016llX ---------------- %p%s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
					"RWB", i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
					(unsigned long long)le64_to_cpu(u1->a),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
					(unsigned long long)le64_to_cpu(u1->b),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
					buffer_info->skb, next_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %p%s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
					"R  ", i,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
					(unsigned long long)le64_to_cpu(u1->a),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
					(unsigned long long)le64_to_cpu(u1->b),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
					(unsigned long long)buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
					buffer_info->skb, next_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
				if (netif_msg_pktdata(adapter) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
				    buffer_info->skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
					print_hex_dump(KERN_INFO, "",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
						       DUMP_PREFIX_ADDRESS, 16,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
						       1,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
						       buffer_info->skb->data,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
						       adapter->rx_buffer_len,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
						       true);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
 * e1000_desc_unused - calculate if we have unused descriptors
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
static int e1000_desc_unused(struct e1000_ring *ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	if (ring->next_to_clean > ring->next_to_use)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
		return ring->next_to_clean - ring->next_to_use - 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
 * e1000e_systim_to_hwtstamp - convert system time value to hw time stamp
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
 * @hwtstamps: time stamp structure to update
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
 * @systim: unsigned 64bit system time value.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
 * Convert the system time value stored in the RX/TXSTMP registers into a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
 * hwtstamp which can be used by the upper level time stamping functions.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
 * The 'systim_lock' spinlock is used to protect the consistency of the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
 * system time value. This is needed because reading the 64 bit time
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
 * value involves reading two 32 bit registers. The first read latches the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
 * value.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
static void e1000e_systim_to_hwtstamp(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
				      struct skb_shared_hwtstamps *hwtstamps,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
				      u64 systim)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	u64 ns;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	unsigned long flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	spin_lock_irqsave(&adapter->systim_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	ns = timecounter_cyc2time(&adapter->tc, systim);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	spin_unlock_irqrestore(&adapter->systim_lock, flags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	memset(hwtstamps, 0, sizeof(*hwtstamps));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	hwtstamps->hwtstamp = ns_to_ktime(ns);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
 * e1000e_rx_hwtstamp - utility function which checks for Rx time stamp
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
 * @status: descriptor extended error and status field
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
 * @skb: particular skb to include time stamp
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
 * If the time stamp is valid, convert it into the timecounter ns value
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
 * and store that result into the shhwtstamps structure which is passed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
 * up the network stack.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
static void e1000e_rx_hwtstamp(struct e1000_adapter *adapter, u32 status,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
			       struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	u64 rxstmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	    !(status & E1000_RXDEXT_STATERR_TST) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	    !(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	/* The Rx time stamp registers contain the time stamp.  No other
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	 * received packet will be time stamped until the Rx time stamp
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	 * registers are read.  Because only one packet can be time stamped
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	 * at a time, the register values must belong to this packet and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	 * therefore none of the other additional attributes need to be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	 * compared.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	rxstmp = (u64)er32(RXSTMPL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	rxstmp |= (u64)er32(RXSTMPH) << 32;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	e1000e_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), rxstmp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	adapter->flags2 &= ~FLAG2_CHECK_RX_HWTSTAMP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 * e1000_receive_skb - helper function to handle Rx indications
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
 * @staterr: descriptor extended error and status field as written by hardware
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
 * @skb: pointer to sk_buff to be indicated to stack
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
static void e1000_receive_skb(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
			      struct net_device *netdev, struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
			      u32 staterr, __le16 vlan)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	u16 tag = le16_to_cpu(vlan);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	e1000e_rx_hwtstamp(adapter, staterr, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	skb->protocol = eth_type_trans(skb, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	if (staterr & E1000_RXD_STAT_VP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tag);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	napi_gro_receive(&adapter->napi, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
 * e1000_rx_checksum - Receive Checksum Offload
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
 * @status_err: receive descriptor status and error fields
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
 * @csum: receive descriptor csum field
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
 * @sk_buff: socket buffer with received data
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
			      struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	u16 status = (u16)status_err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	u8 errors = (u8)(status_err >> 24);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	skb_checksum_none_assert(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	/* Rx checksum disabled */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	if (!(adapter->netdev->features & NETIF_F_RXCSUM))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	/* Ignore Checksum bit is set */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	if (status & E1000_RXD_STAT_IXSM)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	/* TCP/UDP checksum error bit or IP checksum error bit is set */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		/* let the stack verify checksum errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		adapter->hw_csum_err++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	/* TCP/UDP Checksum has not been calculated */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	/* It must be a TCP or UDP packet with a valid checksum */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	skb->ip_summed = CHECKSUM_UNNECESSARY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	adapter->hw_csum_good++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	s32 ret_val = __ew32_prepare(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	writel(i, rx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		u32 rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		e_err("ME firmware caused invalid RDT - resetting\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	s32 ret_val = __ew32_prepare(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	writel(i, tx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		u32 tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		ew32(TCTL, tctl & ~E1000_TCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		e_err("ME firmware caused invalid TDT - resetting\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
		schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
 * e1000_alloc_rx_buffers - Replace used receive buffers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
				   int cleaned_count, gfp_t gfp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	union e1000_rx_desc_extended *rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
	unsigned int bufsz = adapter->rx_buffer_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	i = rx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	while (cleaned_count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
		if (skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
			skb_trim(skb, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
			goto map_skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		if (!skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
			/* Better luck next round */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
			adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
map_skb:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
						  adapter->rx_buffer_len,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
						  DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
			dev_err(&pdev->dev, "Rx DMA map failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
			adapter->rx_dma_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
			/* Force memory writes to complete before letting h/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
			 * know there are new descriptors to fetch.  (Only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
			 * applicable for weak-ordered memory model archs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
			 * such as IA-64).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
			wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
				e1000e_update_rdt_wa(rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
				writel(i, rx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
		i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
		if (i == rx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	rx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
				      int cleaned_count, gfp_t gfp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	union e1000_rx_desc_packet_split *rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	struct e1000_ps_page *ps_page;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	unsigned int i, j;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	i = rx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	while (cleaned_count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
			ps_page = &buffer_info->ps_pages[j];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
			if (j >= adapter->rx_ps_pages) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
				/* all unused desc entries get hw null ptr */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
				rx_desc->read.buffer_addr[j + 1] =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
				    ~cpu_to_le64(0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
				continue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
			if (!ps_page->page) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
				ps_page->page = alloc_page(gfp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
				if (!ps_page->page) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
					adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
					goto no_buffers;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
				ps_page->dma = dma_map_page(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
							    ps_page->page,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
							    0, PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
							    DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
				if (dma_mapping_error(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
						      ps_page->dma)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
					dev_err(&adapter->pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
						"Rx DMA page map failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
					adapter->rx_dma_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
					goto no_buffers;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
			/* Refresh the desc even if buffer_addrs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
			 * didn't change because each write-back
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
			 * erases this info.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
			rx_desc->read.buffer_addr[j + 1] =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
			    cpu_to_le64(ps_page->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
		skb = __netdev_alloc_skb_ip_align(netdev, adapter->rx_ps_bsize0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
						  gfp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		if (!skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
			adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
						  adapter->rx_ps_bsize0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
						  DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
			dev_err(&pdev->dev, "Rx DMA map failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
			adapter->rx_dma_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
			/* cleanup skb */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
			dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
			buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
			/* Force memory writes to complete before letting h/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
			 * know there are new descriptors to fetch.  (Only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
			 * applicable for weak-ordered memory model archs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
			 * such as IA-64).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
			wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
				e1000e_update_rdt_wa(rx_ring, i << 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
				writel(i << 1, rx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
		if (i == rx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
no_buffers:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
	rx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
 * @cleaned_count: number of buffers to allocate this pass
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
					 int cleaned_count, gfp_t gfp)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	union e1000_rx_desc_extended *rx_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	unsigned int bufsz = 256 - 16;	/* for skb_reserve */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
	i = rx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	while (cleaned_count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
		if (skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
			skb_trim(skb, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
			goto check_page;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
		if (unlikely(!skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
			/* Better luck next round */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
			adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
		buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
check_page:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
		/* allocate a new page if necessary */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		if (!buffer_info->page) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
			buffer_info->page = alloc_page(gfp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
			if (unlikely(!buffer_info->page)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
				adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
		if (!buffer_info->dma) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
			buffer_info->dma = dma_map_page(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
							buffer_info->page, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
							PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
							DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
				adapter->alloc_rx_buff_failed++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
		if (unlikely(++i == rx_ring->count))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	if (likely(rx_ring->next_to_use != i)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
		rx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		if (unlikely(i-- == 0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
			i = (rx_ring->count - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		/* Force memory writes to complete before letting h/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		 * know there are new descriptors to fetch.  (Only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		 * applicable for weak-ordered memory model archs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		 * such as IA-64).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
			e1000e_update_rdt_wa(rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
			writel(i, rx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
				 struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	if (netdev->features & NETIF_F_RXHASH)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		skb->rxhash = le32_to_cpu(rss);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
 * e1000_clean_rx_irq - Send received data up the network stack
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
 * the return value indicates whether actual cleaning was done, there
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
 * is no guarantee that everything was cleaned
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
			       int work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	struct e1000_buffer *buffer_info, *next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	u32 length, staterr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	int cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	bool cleaned = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	i = rx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	while (staterr & E1000_RXD_STAT_DD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
		struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		if (*work_done >= work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
		(*work_done)++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
		rmb();	/* read descriptor and rx_buffer_info after status DD */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
		prefetch(skb->data - NET_IP_ALIGN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
		i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		if (i == rx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		prefetch(next_rxd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		next_buffer = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		cleaned = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		cleaned_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		dma_unmap_single(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
				 adapter->rx_buffer_len, DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		length = le16_to_cpu(rx_desc->wb.upper.length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		/* !EOP means multiple descriptors were used to store a single
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
		 * packet, if that's the case we need to toss it.  In fact, we
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
		 * need to toss every packet with the EOP bit clear and the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
		 * next frame that _does_ have the EOP bit set, as it is by
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
		 * definition only a frame fragment
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
		if (unlikely(!(staterr & E1000_RXD_STAT_EOP)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
			adapter->flags2 |= FLAG2_IS_DISCARDING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
			/* All receives must fit into a single buffer */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
			e_dbg("Receive packet consumed multiple buffers\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
			/* recycle */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
			buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
			if (staterr & E1000_RXD_STAT_EOP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
			     !(netdev->features & NETIF_F_RXALL))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
			/* recycle */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
			buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		/* adjust length to remove Ethernet CRC */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
			/* If configured to store CRC, don't subtract FCS,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
			 * but keep the FCS bytes out of the total_rx_bytes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
			 * counter
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
			if (netdev->features & NETIF_F_RXFCS)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
				total_rx_bytes -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
				length -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
		total_rx_bytes += length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
		total_rx_packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		/* code added for copybreak, this should improve
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		 * performance for small packets with large amounts
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
		 * of reassembly being done in the stack
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		if (length < copybreak) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
			struct sk_buff *new_skb =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
			    netdev_alloc_skb_ip_align(netdev, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
			if (new_skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
				skb_copy_to_linear_data_offset(new_skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
							       -NET_IP_ALIGN,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
							       (skb->data -
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
								NET_IP_ALIGN),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
							       (length +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
								NET_IP_ALIGN));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
				/* save the skb in buffer_info as good */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
				buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
				skb = new_skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
			/* else just continue with the old one */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
		/* end copybreak code */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		skb_put(skb, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		/* Receive Checksum Offload */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		e1000_rx_checksum(adapter, staterr, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		e1000_receive_skb(adapter, netdev, skb, staterr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
				  rx_desc->wb.upper.vlan);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
next_desc:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
		/* return some buffers to hardware, one at a time is too slow */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
					      GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
			cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		/* use prefetched values */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		rx_desc = next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		buffer_info = next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	rx_ring->next_to_clean = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	cleaned_count = e1000_desc_unused(rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	if (cleaned_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	adapter->total_rx_bytes += total_rx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	adapter->total_rx_packets += total_rx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
	return cleaned;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
static void e1000_put_txbuf(struct e1000_ring *tx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
			    struct e1000_buffer *buffer_info)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	if (buffer_info->dma) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		if (buffer_info->mapped_as_page)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
				       buffer_info->length, DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
					 buffer_info->length, DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	if (buffer_info->skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		dev_kfree_skb_any(buffer_info->skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	buffer_info->time_stamp = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
static void e1000_print_hw_hang(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	struct e1000_adapter *adapter = container_of(work,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
						     struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
						     print_hang_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	struct e1000_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	unsigned int i = tx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	u16 phy_status, phy_1000t_status, phy_ext_status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	u16 pci_status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	if (test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	if (!adapter->tx_hang_recheck && (adapter->flags2 & FLAG2_DMA_BURST)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		/* May be block on write-back, flush and detect again
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		 * flush pending descriptor writebacks to memory
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		/* execute the writes immediately */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		/* Due to rare timing issues, write to TIDV again to ensure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		 * the write is successful
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		/* execute the writes immediately */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		adapter->tx_hang_recheck = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	/* Real hang detected */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	adapter->tx_hang_recheck = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	netif_stop_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	e1e_rphy(hw, MII_BMSR, &phy_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	e1e_rphy(hw, MII_STAT1000, &phy_1000t_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	e1e_rphy(hw, MII_ESTATUS, &phy_ext_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	/* detected Hardware unit hang */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	e_err("Detected Hardware Unit Hang:\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	      "  TDH                  <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	      "  TDT                  <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	      "  next_to_use          <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	      "  next_to_clean        <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	      "buffer_info[next_to_clean]:\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	      "  time_stamp           <%lx>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	      "  next_to_watch        <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	      "  jiffies              <%lx>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	      "  next_to_watch.status <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	      "MAC Status             <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	      "PHY Status             <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	      "PHY 1000BASE-T Status  <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	      "PHY Extended Status    <%x>\n"
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	      "PCI Status             <%x>\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	      readl(tx_ring->head), readl(tx_ring->tail), tx_ring->next_to_use,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	      tx_ring->next_to_clean, tx_ring->buffer_info[eop].time_stamp,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	      eop, jiffies, eop_desc->upper.fields.status, er32(STATUS),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	      phy_status, phy_1000t_status, phy_ext_status, pci_status);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	/* Suggest workaround for known h/w issue */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
	if ((hw->mac.type == e1000_pchlan) && (er32(CTRL) & E1000_CTRL_TFCE))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		e_err("Try turning off Tx pause (flow control) via ethtool\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
 * e1000e_tx_hwtstamp_work - check for Tx time stamp
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
 * @work: pointer to work struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
 * This work function polls the TSYNCTXCTL valid bit to determine when a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
 * timestamp has been taken for the current stored skb.  The timestamp must
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
 * be for this skb because only one such packet is allowed in the queue.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
static void e1000e_tx_hwtstamp_work(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	struct e1000_adapter *adapter = container_of(work, struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
						     tx_hwtstamp_work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	if (!adapter->tx_hwtstamp_skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		struct skb_shared_hwtstamps shhwtstamps;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		u64 txstmp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		txstmp = er32(TXSTMPL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		txstmp |= (u64)er32(TXSTMPH) << 32;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		e1000e_systim_to_hwtstamp(adapter, &shhwtstamps, txstmp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
		dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		adapter->tx_hwtstamp_skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		/* reschedule to check later */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		schedule_work(&adapter->tx_hwtstamp_work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
 * @tx_ring: Tx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
 * the return value indicates whether actual cleaning was done, there
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
 * is no guarantee that everything was cleaned
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	struct e1000_tx_desc *tx_desc, *eop_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	unsigned int i, eop;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	unsigned int count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	unsigned int bytes_compl = 0, pkts_compl = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	i = tx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	eop = tx_ring->buffer_info[i].next_to_watch;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	       (count < tx_ring->count)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		bool cleaned = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		rmb(); /* read buffer_info after eop_desc */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		for (; !cleaned; count++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
			tx_desc = E1000_TX_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
			buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
			cleaned = (i == eop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
			if (cleaned) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
				total_tx_packets += buffer_info->segs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
				total_tx_bytes += buffer_info->bytecount;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
				if (buffer_info->skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
					bytes_compl += buffer_info->skb->len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
					pkts_compl++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
			e1000_put_txbuf(tx_ring, buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
			tx_desc->upper.data = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
			i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
			if (i == tx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
				i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		if (i == tx_ring->next_to_use)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		eop = tx_ring->buffer_info[i].next_to_watch;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	tx_ring->next_to_clean = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
#define TX_WAKE_THRESHOLD 32
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	if (count && netif_carrier_ok(netdev) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		/* Make sure that anybody stopping the queue after this
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		 * sees the new next_to_clean.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		smp_mb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		if (netif_queue_stopped(netdev) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
			netif_wake_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
			++adapter->restart_queue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
	if (adapter->detect_tx_hung) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		/* Detect a transmit hang in hardware, this serializes the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		 * check with the clearing of time_stamp and movement of i
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
		adapter->detect_tx_hung = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
		if (tx_ring->buffer_info[i].time_stamp &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
			       + (adapter->tx_timeout_factor * HZ)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		    !(er32(STATUS) & E1000_STATUS_TXOFF))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
			schedule_work(&adapter->print_hang_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
			adapter->tx_hang_recheck = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	adapter->total_tx_bytes += total_tx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	adapter->total_tx_packets += total_tx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	return count < tx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 * the return value indicates whether actual cleaning was done, there
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
 * is no guarantee that everything was cleaned
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
				  int work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	struct e1000_buffer *buffer_info, *next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	struct e1000_ps_page *ps_page;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	unsigned int i, j;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	u32 length, staterr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	int cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	bool cleaned = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	i = rx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	while (staterr & E1000_RXD_STAT_DD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		if (*work_done >= work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
		(*work_done)++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		rmb();	/* read descriptor and rx_buffer_info after status DD */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		/* in the packet split case this is header only */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		prefetch(skb->data - NET_IP_ALIGN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
		i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		if (i == rx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		prefetch(next_rxd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
		next_buffer = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
		cleaned = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		cleaned_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		dma_unmap_single(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
				 adapter->rx_ps_bsize0, DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
		/* see !EOP comment in other Rx routine */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
		if (!(staterr & E1000_RXD_STAT_EOP))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
			adapter->flags2 |= FLAG2_IS_DISCARDING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
			e_dbg("Packet Split buffers didn't pick up the full packet\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
			dev_kfree_skb_irq(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
			if (staterr & E1000_RXD_STAT_EOP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
			     !(netdev->features & NETIF_F_RXALL))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
			dev_kfree_skb_irq(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
		length = le16_to_cpu(rx_desc->wb.middle.length0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
		if (!length) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
			e_dbg("Last part of the packet spanning multiple descriptors\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
			dev_kfree_skb_irq(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
		/* Good Receive */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
		skb_put(skb, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
			/* this looks ugly, but it seems compiler issues make
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
			 * it more efficient than reusing j
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
			int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
			/* page alloc/put takes too long and effects small
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
			 * packet throughput, so unsplit small packets and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
			 * save the alloc/put only valid in softirq (napi)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
			 * context to call kmap_*
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
			if (l1 && (l1 <= copybreak) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
			    ((length + l1) <= adapter->rx_ps_bsize0)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
				u8 *vaddr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
				ps_page = &buffer_info->ps_pages[0];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
				/* there is no documentation about how to call
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
				 * kmap_atomic, so we can't hold the mapping
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
				 * very long
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
				dma_sync_single_for_cpu(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
							ps_page->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
							PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
							DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
				vaddr = kmap_atomic(ps_page->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
				memcpy(skb_tail_pointer(skb), vaddr, l1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
				kunmap_atomic(vaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
				dma_sync_single_for_device(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
							   ps_page->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
							   PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
							   DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
				/* remove the CRC */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
				if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
					if (!(netdev->features & NETIF_F_RXFCS))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
						l1 -= 4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
				skb_put(skb, l1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
				goto copydone;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
			} /* if */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
			if (!length)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
			ps_page = &buffer_info->ps_pages[j];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
				       DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
			ps_page->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
			skb_fill_page_desc(skb, j, ps_page->page, 0, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
			ps_page->page = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
			skb->len += length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
			skb->data_len += length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
			skb->truesize += PAGE_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		/* strip the ethernet crc, problem is we're using pages now so
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		 * this whole operation can get a little cpu intensive
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
			if (!(netdev->features & NETIF_F_RXFCS))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
				pskb_trim(skb, skb->len - 4);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
copydone:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
		total_rx_bytes += skb->len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		total_rx_packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		e1000_rx_checksum(adapter, staterr, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		if (rx_desc->wb.upper.header_status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		    cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
			adapter->rx_hdr_split++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
		e1000_receive_skb(adapter, netdev, skb, staterr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
				  rx_desc->wb.middle.vlan);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
next_desc:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
		/* return some buffers to hardware, one at a time is too slow */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
					      GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
			cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		/* use prefetched values */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		rx_desc = next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
		buffer_info = next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	rx_ring->next_to_clean = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	cleaned_count = e1000_desc_unused(rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
	if (cleaned_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	adapter->total_rx_bytes += total_rx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	adapter->total_rx_packets += total_rx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	return cleaned;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
 * e1000_consume_page - helper function
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
			       u16 length)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	bi->page = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	skb->len += length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	skb->data_len += length;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	skb->truesize += PAGE_SIZE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
 * the return value indicates whether actual cleaning was done, there
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
 * is no guarantee that everything was cleaned
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
				     int work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	struct e1000_buffer *buffer_info, *next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	u32 length, staterr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	int cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	bool cleaned = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	struct skb_shared_info *shinfo;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	i = rx_ring->next_to_clean;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
	while (staterr & E1000_RXD_STAT_DD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		struct sk_buff *skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		if (*work_done >= work_to_do)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
		(*work_done)++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
		rmb();	/* read descriptor and rx_buffer_info after status DD */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		skb = buffer_info->skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		++i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		if (i == rx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		prefetch(next_rxd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		next_buffer = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		cleaned = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		cleaned_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		dma_unmap_page(&pdev->dev, buffer_info->dma, PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
			       DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		length = le16_to_cpu(rx_desc->wb.upper.length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
		/* errors is only valid for DD + EOP descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		if (unlikely((staterr & E1000_RXD_STAT_EOP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
			     ((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
			      !(netdev->features & NETIF_F_RXALL)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
			/* recycle both page and skb */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
			buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
			/* an error means any chain goes out the window too */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
			if (rx_ring->rx_skb_top)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
				dev_kfree_skb_irq(rx_ring->rx_skb_top);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
			rx_ring->rx_skb_top = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
#define rxtop (rx_ring->rx_skb_top)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
		if (!(staterr & E1000_RXD_STAT_EOP)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
			/* this descriptor is only the beginning (or middle) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
			if (!rxtop) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
				/* this is the beginning of a chain */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
				rxtop = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
						   0, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
				/* this is the middle of a chain */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
				shinfo = skb_shinfo(rxtop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
				skb_fill_page_desc(rxtop, shinfo->nr_frags,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
						   buffer_info->page, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
						   length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
				/* re-use the skb, only consumed the page */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
				buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
			e1000_consume_page(buffer_info, rxtop, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
			if (rxtop) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
				/* end of the chain */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
				shinfo = skb_shinfo(rxtop);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
				skb_fill_page_desc(rxtop, shinfo->nr_frags,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
						   buffer_info->page, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
						   length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
				/* re-use the current skb, we only consumed the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
				 * page
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
				buffer_info->skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
				skb = rxtop;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
				rxtop = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
				e1000_consume_page(buffer_info, skb, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
			} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
				/* no chain, got EOP, this buf is the packet
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
				 * copybreak to save the put_page/alloc_page
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
				 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
				if (length <= copybreak &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
				    skb_tailroom(skb) >= length) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
					u8 *vaddr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
					vaddr = kmap_atomic(buffer_info->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
					memcpy(skb_tail_pointer(skb), vaddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
					       length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
					kunmap_atomic(vaddr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
					/* re-use the page, so don't erase
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
					 * buffer_info->page
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
					 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
					skb_put(skb, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
				} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
					skb_fill_page_desc(skb, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
							   buffer_info->page, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
							   length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
					e1000_consume_page(buffer_info, skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
							   length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
		/* Receive Checksum Offload */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
		e1000_rx_checksum(adapter, staterr, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		/* probably a little skewed due to removing CRC */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		total_rx_bytes += skb->len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		total_rx_packets++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		/* eth type trans needs skb->data to point to something */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		if (!pskb_may_pull(skb, ETH_HLEN)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
			e_err("pskb_may_pull failed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
			dev_kfree_skb_irq(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
			goto next_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		e1000_receive_skb(adapter, netdev, skb, staterr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
				  rx_desc->wb.upper.vlan);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
next_desc:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
		/* return some buffers to hardware, one at a time is too slow */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
					      GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
			cleaned_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		/* use prefetched values */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		rx_desc = next_rxd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		buffer_info = next_buffer;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	rx_ring->next_to_clean = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	cleaned_count = e1000_desc_unused(rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	if (cleaned_count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
	adapter->total_rx_bytes += total_rx_bytes;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	adapter->total_rx_packets += total_rx_packets;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
	return cleaned;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	struct e1000_ps_page *ps_page;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
	unsigned int i, j;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
	/* Free all the Rx ring sk_buffs */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	for (i = 0; i < rx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
		if (buffer_info->dma) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
			if (adapter->clean_rx == e1000_clean_rx_irq)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
				dma_unmap_single(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
						 adapter->rx_buffer_len,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
						 DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
				dma_unmap_page(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
					       PAGE_SIZE, DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
				dma_unmap_single(&pdev->dev, buffer_info->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
						 adapter->rx_ps_bsize0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
						 DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		if (buffer_info->page) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			put_page(buffer_info->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
			buffer_info->page = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		if (buffer_info->skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
			dev_kfree_skb(buffer_info->skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
			buffer_info->skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
			ps_page = &buffer_info->ps_pages[j];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
			if (!ps_page->page)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
				       DMA_FROM_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
			ps_page->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
			put_page(ps_page->page);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
			ps_page->page = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
	/* there also may be some cached data from a chained receive */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	if (rx_ring->rx_skb_top) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		dev_kfree_skb(rx_ring->rx_skb_top);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		rx_ring->rx_skb_top = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	/* Zero out the descriptor ring */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	memset(rx_ring->desc, 0, rx_ring->size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	rx_ring->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	rx_ring->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	writel(0, rx_ring->head);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	if (rx_ring->adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		e1000e_update_rdt_wa(rx_ring, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
		writel(0, rx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
static void e1000e_downshift_workaround(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	struct e1000_adapter *adapter = container_of(work,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
						     struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
						     downshift_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	if (test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
 * e1000_intr_msi - Interrupt Handler
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
 * @irq: interrupt number
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
 * @data: pointer to a network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
static irqreturn_t e1000_intr_msi(int __always_unused irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	u32 icr = er32(ICR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	/* read ICR disables interrupts using IAM */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	if (icr & E1000_ICR_LSC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		hw->mac.get_link_status = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		/* ICH8 workaround-- Call gig speed drop workaround on cable
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		 * disconnect (LSC) before accessing any PHY registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		    (!(er32(STATUS) & E1000_STATUS_LU)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
			schedule_work(&adapter->downshift_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
		/* 80003ES2LAN workaround-- For packet buffer work-around on
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		 * link down event; disable receives here in the ISR and reset
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		 * adapter in watchdog
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		if (netif_carrier_ok(netdev) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
			/* disable receives */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
			u32 rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
			adapter->flags |= FLAG_RESTART_NOW;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		/* guard against interrupt when we're going down */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	/* Reset on uncorrectable ECC error */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		u32 pbeccsts = er32(PBECCSTS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		adapter->corr_errors +=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		adapter->uncorr_errors +=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		/* Do the reset outside of interrupt context */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		/* return immediately since reset is imminent */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	if (napi_schedule_prep(&adapter->napi)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		adapter->total_tx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		adapter->total_tx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		adapter->total_rx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		adapter->total_rx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		__napi_schedule(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
 * e1000_intr - Interrupt Handler
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
 * @irq: interrupt number
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
 * @data: pointer to a network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
static irqreturn_t e1000_intr(int __always_unused irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	u32 rctl, icr = er32(ICR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		return IRQ_NONE;  /* Not our interrupt */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	 * not set, then the adapter didn't send an interrupt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
	if (!(icr & E1000_ICR_INT_ASSERTED))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
		return IRQ_NONE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	/* Interrupt Auto-Mask...upon reading ICR,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	 * interrupts are masked.  No need for the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	 * IMC write
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	if (icr & E1000_ICR_LSC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		hw->mac.get_link_status = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		/* ICH8 workaround-- Call gig speed drop workaround on cable
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		 * disconnect (LSC) before accessing any PHY registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
		    (!(er32(STATUS) & E1000_STATUS_LU)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
			schedule_work(&adapter->downshift_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		/* 80003ES2LAN workaround--
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		 * For packet buffer work-around on link down event;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		 * disable receives here in the ISR and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		 * reset adapter in watchdog
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
		if (netif_carrier_ok(netdev) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
			/* disable receives */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
			rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
			adapter->flags |= FLAG_RESTART_NOW;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
		/* guard against interrupt when we're going down */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
		if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	/* Reset on uncorrectable ECC error */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
		u32 pbeccsts = er32(PBECCSTS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		adapter->corr_errors +=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
		adapter->uncorr_errors +=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
		/* Do the reset outside of interrupt context */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		/* return immediately since reset is imminent */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
		return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	if (napi_schedule_prep(&adapter->napi)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		adapter->total_tx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
		adapter->total_tx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		adapter->total_rx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		adapter->total_rx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		__napi_schedule(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	u32 icr = er32(ICR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
			ew32(IMS, E1000_IMS_OTHER);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		return IRQ_NONE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	if (icr & adapter->eiac_mask)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		ew32(ICS, (icr & adapter->eiac_mask));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	if (icr & E1000_ICR_OTHER) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		if (!(icr & E1000_ICR_LSC))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
			goto no_link_interrupt;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		hw->mac.get_link_status = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		/* guard against interrupt when we're going down */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
no_link_interrupt:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
static irqreturn_t e1000_intr_msix_tx(int __always_unused irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
	struct e1000_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	adapter->total_tx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	adapter->total_tx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	if (!e1000_clean_tx_irq(tx_ring))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
		/* Ring was not completely cleaned, so fire another interrupt */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
		ew32(ICS, tx_ring->ims_val);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
static irqreturn_t e1000_intr_msix_rx(int __always_unused irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	struct e1000_ring *rx_ring = adapter->rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	/* Write the ITR value calculated at the end of the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	 * previous interrupt.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	if (rx_ring->set_itr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
		writel(1000000000 / (rx_ring->itr_val * 256),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
		       rx_ring->itr_register);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
		rx_ring->set_itr = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	if (napi_schedule_prep(&adapter->napi)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
		adapter->total_rx_bytes = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
		adapter->total_rx_packets = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		__napi_schedule(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
 * e1000_configure_msix - Configure MSI-X hardware
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
 * e1000_configure_msix sets up the hardware to properly
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
 * generate MSI-X interrupts.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
static void e1000_configure_msix(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	struct e1000_ring *rx_ring = adapter->rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	struct e1000_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	int vector = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	u32 ctrl_ext, ivar = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	adapter->eiac_mask = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	if (hw->mac.type == e1000_82574) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
		u32 rfctl = er32(RFCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
		rfctl |= E1000_RFCTL_ACK_DIS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		ew32(RFCTL, rfctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	/* Configure Rx vector */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
	rx_ring->ims_val = E1000_IMS_RXQ0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	adapter->eiac_mask |= rx_ring->ims_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	if (rx_ring->itr_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
		writel(1000000000 / (rx_ring->itr_val * 256),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		       rx_ring->itr_register);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		writel(1, rx_ring->itr_register);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
	/* Configure Tx vector */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	tx_ring->ims_val = E1000_IMS_TXQ0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
	vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
	if (tx_ring->itr_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
		writel(1000000000 / (tx_ring->itr_val * 256),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
		       tx_ring->itr_register);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
		writel(1, tx_ring->itr_register);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
	adapter->eiac_mask |= tx_ring->ims_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	/* set vector for Other Causes, e.g. link changes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	if (rx_ring->itr_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
		writel(1000000000 / (rx_ring->itr_val * 256),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
		       hw->hw_addr + E1000_EITR_82574(vector));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	/* Cause Tx interrupts on every write back */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	ivar |= (1 << 31);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	ew32(IVAR, ivar);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	/* enable MSI-X PBA support */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	ctrl_ext = er32(CTRL_EXT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	/* Auto-Mask Other interrupts upon ICR read */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	ew32(CTRL_EXT, ctrl_ext);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		pci_disable_msix(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		kfree(adapter->msix_entries);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		adapter->msix_entries = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
		pci_disable_msi(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		adapter->flags &= ~FLAG_MSI_ENABLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
 * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
 * Attempt to configure interrupts using the best available
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
 * capabilities of the hardware and kernel.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	switch (adapter->int_mode) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	case E1000E_INT_MODE_MSIX:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
		if (adapter->flags & FLAG_HAS_MSIX) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
			adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
			adapter->msix_entries = kcalloc(adapter->num_vectors,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
							sizeof(struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
							       msix_entry),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
							GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
			if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
				for (i = 0; i < adapter->num_vectors; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
					adapter->msix_entries[i].entry = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
				err = pci_enable_msix(adapter->pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
						      adapter->msix_entries,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
						      adapter->num_vectors);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
				if (err == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
					return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
			/* MSI-X failed, so fall through and try MSI */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
			e_err("Failed to initialize MSI-X interrupts.  Falling back to MSI interrupts.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
			e1000e_reset_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		adapter->int_mode = E1000E_INT_MODE_MSI;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		/* Fall through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	case E1000E_INT_MODE_MSI:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
		if (!pci_enable_msi(adapter->pdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			adapter->flags |= FLAG_MSI_ENABLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
			e_err("Failed to initialize MSI interrupts.  Falling back to legacy interrupts.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		/* Fall through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	case E1000E_INT_MODE_LEGACY:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		/* Don't do anything; this is the system default */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	/* store the number of vectors being used */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	adapter->num_vectors = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
 * e1000_request_msix - Initialize MSI-X interrupts
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
 * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
 * kernel.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
static int e1000_request_msix(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	int err = 0, vector = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
		snprintf(adapter->rx_ring->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
			 sizeof(adapter->rx_ring->name) - 1,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
			 "%s-rx-0", netdev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	err = request_irq(adapter->msix_entries[vector].vector,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
			  netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
		return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	adapter->rx_ring->itr_register = adapter->hw.hw_addr +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	    E1000_EITR_82574(vector);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	adapter->rx_ring->itr_val = adapter->itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		snprintf(adapter->tx_ring->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
			 sizeof(adapter->tx_ring->name) - 1,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
			 "%s-tx-0", netdev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
	err = request_irq(adapter->msix_entries[vector].vector,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
			  netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
		return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	adapter->tx_ring->itr_register = adapter->hw.hw_addr +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
	    E1000_EITR_82574(vector);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	adapter->tx_ring->itr_val = adapter->itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	err = request_irq(adapter->msix_entries[vector].vector,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
			  e1000_msix_other, 0, netdev->name, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	e1000_configure_msix(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
 * e1000_request_irq - initialize interrupts
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
 * Attempts to configure interrupts using the best available
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
 * capabilities of the hardware and kernel.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
static int e1000_request_irq(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
		err = e1000_request_msix(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
		if (!err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
			return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		/* fall back to MSI */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
		e1000e_reset_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
		adapter->int_mode = E1000E_INT_MODE_MSI;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		e1000e_set_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	if (adapter->flags & FLAG_MSI_ENABLED) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
		err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
				  netdev->name, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
		if (!err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
			return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
		/* fall back to legacy interrupt */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
		e1000e_reset_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
			  netdev->name, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
		e_err("Unable to allocate interrupt, Error: %d\n", err);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
static void e1000_free_irq(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		int vector = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		free_irq(adapter->msix_entries[vector].vector, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
		vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
		free_irq(adapter->msix_entries[vector].vector, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		/* Other Causes interrupt vector */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		free_irq(adapter->msix_entries[vector].vector, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	free_irq(adapter->pdev->irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
 * e1000_irq_disable - Mask off interrupt generation on the NIC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
static void e1000_irq_disable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	ew32(IMC, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	if (adapter->msix_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
		ew32(EIAC_82574, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
		int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
		for (i = 0; i < adapter->num_vectors; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
			synchronize_irq(adapter->msix_entries[i].vector);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
		synchronize_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
 * e1000_irq_enable - Enable default interrupt generation settings
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
static void e1000_irq_enable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	} else if (hw->mac.type == e1000_pch_lpt) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
		ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
		ew32(IMS, IMS_ENABLE_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
 * e1000e_get_hw_control - get control of the h/w from f/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
 * e1000e_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
 * For ASF and Pass Through versions of f/w this means that
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
 * the driver is loaded. For AMT version (only with 82573)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
 * of the f/w this means that the network i/f is open.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
void e1000e_get_hw_control(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	u32 ctrl_ext;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	u32 swsm;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	/* Let firmware know the driver has taken over */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		swsm = er32(SWSM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
		ctrl_ext = er32(CTRL_EXT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
 * e1000e_release_hw_control - release control of the h/w to f/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
 * e1000e_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
 * For ASF and Pass Through versions of f/w this means that the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
 * driver is no longer loaded. For AMT version (only with 82573) i
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
 * of the f/w this means that the network i/f is closed.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
void e1000e_release_hw_control(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	u32 ctrl_ext;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	u32 swsm;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	/* Let firmware taken over control of h/w */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
		swsm = er32(SWSM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
		ctrl_ext = er32(CTRL_EXT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
 * e1000_alloc_ring_dma - allocate memory for a ring structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
				struct e1000_ring *ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
					GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	if (!ring->desc)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
 * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
 * @tx_ring: Tx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 * Return 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
int e1000e_setup_tx_resources(struct e1000_ring *tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	int err = -ENOMEM, size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	size = sizeof(struct e1000_buffer) * tx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	tx_ring->buffer_info = vzalloc(size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	if (!tx_ring->buffer_info)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
		goto err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	/* round up to nearest 4K */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	tx_ring->size = ALIGN(tx_ring->size, 4096);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	err = e1000_alloc_ring_dma(adapter, tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
		goto err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	tx_ring->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	tx_ring->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
err:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	vfree(tx_ring->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
 * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
int e1000e_setup_rx_resources(struct e1000_ring *rx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	int i, size, desc_len, err = -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	size = sizeof(struct e1000_buffer) * rx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	rx_ring->buffer_info = vzalloc(size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	if (!rx_ring->buffer_info)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		goto err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
	for (i = 0; i < rx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
						sizeof(struct e1000_ps_page),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
						GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
		if (!buffer_info->ps_pages)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
			goto err_pages;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	desc_len = sizeof(union e1000_rx_desc_packet_split);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	/* Round up to nearest 4K */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
	rx_ring->size = rx_ring->count * desc_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	rx_ring->size = ALIGN(rx_ring->size, 4096);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	err = e1000_alloc_ring_dma(adapter, rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
		goto err_pages;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	rx_ring->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	rx_ring->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	rx_ring->rx_skb_top = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
err_pages:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	for (i = 0; i < rx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
		buffer_info = &rx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
		kfree(buffer_info->ps_pages);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
err:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
	vfree(rx_ring->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	e_err("Unable to allocate memory for the receive descriptor ring\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
 * e1000_clean_tx_ring - Free Tx Buffers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
 * @tx_ring: Tx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
	unsigned long size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
	for (i = 0; i < tx_ring->count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
		e1000_put_txbuf(tx_ring, buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	netdev_reset_queue(adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	size = sizeof(struct e1000_buffer) * tx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	memset(tx_ring->buffer_info, 0, size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	memset(tx_ring->desc, 0, tx_ring->size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	tx_ring->next_to_use = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
	tx_ring->next_to_clean = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	writel(0, tx_ring->head);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	if (tx_ring->adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
		e1000e_update_tdt_wa(tx_ring, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
		writel(0, tx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
 * e1000e_free_tx_resources - Free Tx Resources per Queue
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
 * @tx_ring: Tx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
 * Free all transmit software resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
void e1000e_free_tx_resources(struct e1000_ring *tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	e1000_clean_tx_ring(tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	vfree(tx_ring->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	tx_ring->buffer_info = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
			  tx_ring->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	tx_ring->desc = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
 * e1000e_free_rx_resources - Free Rx Resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
 * @rx_ring: Rx descriptor ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
 * Free all receive software resources
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
void e1000e_free_rx_resources(struct e1000_ring *rx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	struct e1000_adapter *adapter = rx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	e1000_clean_rx_ring(rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	for (i = 0; i < rx_ring->count; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
		kfree(rx_ring->buffer_info[i].ps_pages);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	vfree(rx_ring->buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	rx_ring->buffer_info = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
			  rx_ring->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	rx_ring->desc = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
 * e1000_update_itr - update the dynamic ITR value based on statistics
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
 * @adapter: pointer to adapter
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
 * @itr_setting: current adapter->itr
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
 * @packets: the number of packets during this measurement interval
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
 * @bytes: the number of bytes during this measurement interval
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
 *      Stores a new ITR value based on packets and byte
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
 *      counts during the last interrupt.  The advantage of per interrupt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
 *      computation is faster updates and more accurate ITR for the current
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
 *      traffic pattern.  Constants in this function were computed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
 *      based on theoretical maximum wire speed and thresholds were set based
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
 *      on testing data as well as attempting to minimize response time
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
 *      while increasing bulk throughput.  This functionality is controlled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
 *      by the InterruptThrottleRate module parameter.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
static unsigned int e1000_update_itr(u16 itr_setting, int packets, int bytes)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	unsigned int retval = itr_setting;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	if (packets == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
		return itr_setting;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
	switch (itr_setting) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	case lowest_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
		/* handle TSO and jumbo frames */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		if (bytes / packets > 8000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
			retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		else if ((packets < 5) && (bytes > 512))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
			retval = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	case low_latency:  /* 50 usec aka 20000 ints/s */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
		if (bytes > 10000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
			/* this if handles the TSO accounting */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
			if (bytes / packets > 8000)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
				retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			else if ((packets < 10) || ((bytes / packets) > 1200))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
				retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
			else if ((packets > 35))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
				retval = lowest_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		} else if (bytes / packets > 2000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
			retval = bulk_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		} else if (packets <= 2 && bytes < 512) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
			retval = lowest_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	case bulk_latency: /* 250 usec aka 4000 ints/s */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		if (bytes > 25000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
			if (packets > 35)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
				retval = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		} else if (bytes < 6000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
			retval = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
static void e1000_set_itr(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	u16 current_itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	u32 new_itr = adapter->itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
	if (adapter->link_speed != SPEED_1000) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
		current_itr = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		new_itr = 4000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
		goto set_itr_now;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
	if (adapter->flags2 & FLAG2_DISABLE_AIM) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
		new_itr = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		goto set_itr_now;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
	adapter->tx_itr = e1000_update_itr(adapter->tx_itr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
					   adapter->total_tx_packets,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
					   adapter->total_tx_bytes);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		adapter->tx_itr = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	adapter->rx_itr = e1000_update_itr(adapter->rx_itr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
					   adapter->total_rx_packets,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
					   adapter->total_rx_bytes);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
		adapter->rx_itr = low_latency;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	/* counts and packets in update_itr are dependent on these numbers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
	switch (current_itr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	case lowest_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
		new_itr = 70000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	case low_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
		new_itr = 20000; /* aka hwitr = ~200 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	case bulk_latency:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
		new_itr = 4000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
set_itr_now:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
	if (new_itr != adapter->itr) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		/* this attempts to bias the interrupt rate towards Bulk
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
		 * by adding intermediate steps when interrupt rate is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
		 * increasing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		new_itr = new_itr > adapter->itr ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		    min(adapter->itr + (new_itr >> 2), new_itr) : new_itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		adapter->itr = new_itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
		adapter->rx_ring->itr_val = new_itr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
		if (adapter->msix_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
			adapter->rx_ring->set_itr = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
			e1000e_write_itr(adapter, new_itr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
 * e1000e_write_itr - write the ITR value to the appropriate registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
 * @itr: new ITR value to program
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
 * e1000e_write_itr determines if the adapter is in MSI-X mode
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
 * and, if so, writes the EITR registers with the ITR value.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
 * Otherwise, it writes the ITR value into the ITR register.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
	u32 new_itr = itr ? 1000000000 / (itr * 256) : 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		int vector;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
		for (vector = 0; vector < adapter->num_vectors; vector++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
			writel(new_itr, hw->hw_addr + E1000_EITR_82574(vector));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
		ew32(ITR, new_itr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
 * e1000_alloc_queues - Allocate memory for all rings
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
static int e1000_alloc_queues(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	int size = sizeof(struct e1000_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
	adapter->tx_ring = kzalloc(size, GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	if (!adapter->tx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		goto err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	adapter->tx_ring->count = adapter->tx_ring_count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	adapter->tx_ring->adapter = adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	adapter->rx_ring = kzalloc(size, GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	if (!adapter->rx_ring)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
		goto err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
	adapter->rx_ring->count = adapter->rx_ring_count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	adapter->rx_ring->adapter = adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
err:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	e_err("Unable to allocate memory for queues\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	kfree(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	kfree(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
 * e1000e_poll - NAPI Rx polling callback
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
 * @napi: struct associated with this polling callback
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
 * @weight: number of packets driver is allowed to process this poll
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
static int e1000e_poll(struct napi_struct *napi, int weight)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
						     napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	struct net_device *poll_dev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	int tx_cleaned = 1, work_done = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
	adapter = netdev_priv(poll_dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
	if (!adapter->msix_entries ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
	    (adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
		tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	adapter->clean_rx(adapter->rx_ring, &work_done, weight);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
	if (!tx_cleaned)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
		work_done = weight;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	/* If weight not fully consumed, exit the polling mode */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
	if (work_done < weight) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
		if (adapter->itr_setting & 3)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
			e1000_set_itr(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
		napi_complete(napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
			if (adapter->msix_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
				ew32(IMS, adapter->rx_ring->ims_val);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
				e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	return work_done;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
static int e1000_vlan_rx_add_vid(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
				 __be16 proto, u16 vid)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	u32 vfta, index;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	/* don't update vlan cookie if already programmed */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	if ((adapter->hw.mng_cookie.status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	    (vid == adapter->mng_vlan_id))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	/* add VID to filter table */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
		index = (vid >> 5) & 0x7F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		vfta |= (1 << (vid & 0x1F));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		hw->mac.ops.write_vfta(hw, index, vfta);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	set_bit(vid, adapter->active_vlans);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
				  __be16 proto, u16 vid)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	u32 vfta, index;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
	if ((adapter->hw.mng_cookie.status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
	    (vid == adapter->mng_vlan_id)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		/* release control to f/w */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		e1000e_release_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	/* remove VID from filter table */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		index = (vid >> 5) & 0x7F;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
		vfta &= ~(1 << (vid & 0x1F));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
		hw->mac.ops.write_vfta(hw, index, vfta);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	clear_bit(vid, adapter->active_vlans);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
 * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
		/* disable VLAN receive filtering */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
		rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
			e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
					       adapter->mng_vlan_id);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
 * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		/* enable VLAN receive filtering */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		rctl |= E1000_RCTL_VFE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
		rctl &= ~E1000_RCTL_CFIEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
 * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	/* disable VLAN tag insert/strip */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	ctrl &= ~E1000_CTRL_VME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
 * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	u32 ctrl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
	/* enable VLAN tag insert/strip */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
	ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
	ctrl |= E1000_CTRL_VME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	u16 vid = adapter->hw.mng_cookie.vlan_id;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	u16 old_vid = adapter->mng_vlan_id;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		e1000_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		adapter->mng_vlan_id = vid;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q), old_vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
static void e1000_restore_vlan(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	u16 vid;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	    e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	u32 manc, manc2h, mdef, i, j;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	manc = er32(MANC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	/* enable receiving management packets to the host. this will probably
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	 * generate destination unreachable messages from the host OS, but
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	 * the packets will be handled on SMBUS
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
	manc |= E1000_MANC_EN_MNG2HOST;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
	manc2h = er32(MANC2H);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	switch (hw->mac.type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
		manc2h |= (E1000_MANC2H_PORT_623 | E1000_MANC2H_PORT_664);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
	case e1000_82574:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
	case e1000_82583:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		/* Check if IPMI pass-through decision filter already exists;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		 * if so, enable it.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		for (i = 0, j = 0; i < 8; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
			mdef = er32(MDEF(i));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
			/* Ignore filters with anything other than IPMI ports */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
			if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
				continue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
			/* Enable this decision filter in MANC2H */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
			if (mdef)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
				manc2h |= (1 << i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
			j |= mdef;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		if (j == (E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
		/* Create new decision filter in an empty filter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
		for (i = 0, j = 0; i < 8; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
			if (er32(MDEF(i)) == 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
				ew32(MDEF(i), (E1000_MDEF_PORT_623 |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
					       E1000_MDEF_PORT_664));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
				manc2h |= (1 << 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
				j++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
		if (!j)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
			e_warn("Unable to create IPMI pass-through filter\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	ew32(MANC2H, manc2h);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	ew32(MANC, manc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
 * e1000_configure_tx - Configure Transmit Unit after Reset
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
 * Configure the Tx unit of the MAC after a reset.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
static void e1000_configure_tx(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	struct e1000_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	u64 tdba;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	u32 tdlen, tarc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
	/* Setup the HW Tx Head and Tail descriptor pointers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	tdba = tx_ring->dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	ew32(TDBAL(0), (tdba & DMA_BIT_MASK(32)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	ew32(TDBAH(0), (tdba >> 32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	ew32(TDLEN(0), tdlen);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	ew32(TDH(0), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	ew32(TDT(0), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
	tx_ring->head = adapter->hw.hw_addr + E1000_TDH(0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	tx_ring->tail = adapter->hw.hw_addr + E1000_TDT(0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	/* Set the Tx Interrupt Delay register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	ew32(TIDV, adapter->tx_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	/* Tx irq moderation */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	ew32(TADV, adapter->tx_abs_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
	if (adapter->flags2 & FLAG2_DMA_BURST) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
		u32 txdctl = er32(TXDCTL(0));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
			    E1000_TXDCTL_WTHRESH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		/* set up some performance related parameters to encourage the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		 * hardware to use the bus more efficiently in bursts, depends
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		 * on the tx_int_delay to be enabled,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		 * wthresh = 1 ==> burst write is disabled to avoid Tx stalls
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		 * hthresh = 1 ==> prefetch when one or more available
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		 * pthresh = 0x1f ==> prefetch if internal cache 31 or less
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		 * BEWARE: this seems to work but should be considered first if
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		 * there are Tx hangs or other Tx related bugs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
		txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
		ew32(TXDCTL(0), txdctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
	/* erratum work around: set txdctl the same for both queues */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
	ew32(TXDCTL(1), er32(TXDCTL(0)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		tarc = er32(TARC(0));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		/* set the speed mode bit, we'll clear it if we're not at
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		 * gigabit link later
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
#define SPEED_MODE_BIT (1 << 21)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
		tarc |= SPEED_MODE_BIT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		ew32(TARC(0), tarc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	/* errata: program both queues to unweighted RR */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		tarc = er32(TARC(0));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		tarc |= 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		ew32(TARC(0), tarc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		tarc = er32(TARC(1));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
		tarc |= 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
		ew32(TARC(1), tarc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	/* Setup Transmit Descriptor Settings for eop descriptor */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	/* only set IDE if we are delaying interrupts using the timers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	if (adapter->tx_int_delay)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
	/* enable Report Status bit */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
	hw->mac.ops.config_collision_dist(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
 * e1000_setup_rctl - configure the receive control registers
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
 * @adapter: Board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
static void e1000_setup_rctl(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	u32 rctl, rfctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	u32 pages = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
	/* Workaround Si errata on PCHx - configure jumbo frame flow */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
	if (hw->mac.type >= e1000_pch2lan) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
		s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		if (adapter->netdev->mtu > ETH_DATA_LEN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
			e_dbg("failed to enable jumbo frame workaround mode\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	/* Program MC offset vector base */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	    E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	    (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
	/* Do not Store bad packets */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	rctl &= ~E1000_RCTL_SBP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	/* Enable Long Packet receive */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
		rctl &= ~E1000_RCTL_LPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
		rctl |= E1000_RCTL_LPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	/* Some systems expect that the CRC is included in SMBUS traffic. The
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	 * hardware strips the CRC before sending to both SMBUS (BMC) and to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	 * host memory when this is enabled
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		rctl |= E1000_RCTL_SECRC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
		u16 phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
		e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		phy_data &= 0xfff8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
		phy_data |= (1 << 2);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		e1e_wphy(hw, PHY_REG(770, 26), phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
		e1e_rphy(hw, 22, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
		phy_data &= 0x0fff;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
		phy_data |= (1 << 14);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
		e1e_wphy(hw, 0x10, 0x2823);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		e1e_wphy(hw, 0x11, 0x0003);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
		e1e_wphy(hw, 22, phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	/* Setup buffer sizes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	rctl &= ~E1000_RCTL_SZ_4096;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	rctl |= E1000_RCTL_BSEX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	switch (adapter->rx_buffer_len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	case 2048:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		rctl |= E1000_RCTL_SZ_2048;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		rctl &= ~E1000_RCTL_BSEX;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
	case 4096:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		rctl |= E1000_RCTL_SZ_4096;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	case 8192:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
		rctl |= E1000_RCTL_SZ_8192;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	case 16384:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
		rctl |= E1000_RCTL_SZ_16384;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	/* Enable Extended Status in all Receive Descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	rfctl = er32(RFCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	rfctl |= E1000_RFCTL_EXTEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	ew32(RFCTL, rfctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	/* 82571 and greater support packet-split where the protocol
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	 * header is placed in skb->data and the packet data is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	 * In the case of a non-split, skb->data is linearly filled,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	 * followed by the page buffers.  Therefore, skb->data is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	 * sized to hold the largest protocol header.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	 * allocations using alloc_page take too long for regular MTU
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	 * so only enable packet split for jumbo frames
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	 * Using pages when the page size is greater than 16k wastes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	 * a lot of memory, since we allocate 3 pages at all times
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	 * per packet.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
		adapter->rx_ps_pages = pages;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		adapter->rx_ps_pages = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
	if (adapter->rx_ps_pages) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		u32 psrctl = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		/* Enable Packet split descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		rctl |= E1000_RCTL_DTYP_PS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
		psrctl |= adapter->rx_ps_bsize0 >> E1000_PSRCTL_BSIZE0_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
		switch (adapter->rx_ps_pages) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		case 3:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
			psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE3_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
			/* fall-through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
		case 2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
			psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE2_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
			/* fall-through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		case 1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
			psrctl |= PAGE_SIZE >> E1000_PSRCTL_BSIZE1_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		ew32(PSRCTL, psrctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	/* This is useful for sniffing bad packets. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	if (adapter->netdev->features & NETIF_F_RXALL) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
		/* UPE and MPE will be handled by normal PROMISC logic
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
		 * in e1000e_set_rx_mode
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
		rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
			  E1000_RCTL_DPF | /* Allow filtered pause */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
		 * and that breaks VLANs.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	/* just started the receive unit, no need to restart */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	adapter->flags &= ~FLAG_RESTART_NOW;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
 * e1000_configure_rx - Configure Receive Unit after Reset
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
 * Configure the Rx unit of the MAC after a reset.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
static void e1000_configure_rx(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	struct e1000_ring *rx_ring = adapter->rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	u64 rdba;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	u32 rdlen, rctl, rxcsum, ctrl_ext;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	if (adapter->rx_ps_pages) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
		/* this is a 32 byte descriptor */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
		rdlen = rx_ring->count *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
		    sizeof(union e1000_rx_desc_packet_split);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
		adapter->clean_rx = e1000_clean_rx_irq_ps;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		adapter->clean_rx = e1000_clean_rx_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	/* disable receives while setting up the descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
	usleep_range(10000, 20000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	if (adapter->flags2 & FLAG2_DMA_BURST) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		/* set the writeback threshold (only takes effect if the RDTR
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		 * is set). set GRAN=1 and write back up to 0x4 worth, and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		 * enable prefetching of 0x20 Rx descriptors
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
		 * granularity = 01
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		 * wthresh = 04,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
		 * hthresh = 04,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		 * pthresh = 0x20
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
		ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
		ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
		/* override the delay timers for enabling bursting, only if
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
		 * the value was not set by the user via module options
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		if (adapter->rx_int_delay == DEFAULT_RDTR)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
			adapter->rx_int_delay = BURST_RDTR;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
		if (adapter->rx_abs_int_delay == DEFAULT_RADV)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
			adapter->rx_abs_int_delay = BURST_RADV;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	/* set the Receive Delay Timer Register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	ew32(RDTR, adapter->rx_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	/* irq moderation */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	ew32(RADV, adapter->rx_abs_int_delay);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	if ((adapter->itr_setting != 0) && (adapter->itr != 0))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
		e1000e_write_itr(adapter, adapter->itr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	ctrl_ext = er32(CTRL_EXT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	/* Auto-Mask interrupts upon ICR access */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	ctrl_ext |= E1000_CTRL_EXT_IAME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
	ew32(IAM, 0xffffffff);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	ew32(CTRL_EXT, ctrl_ext);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	 * the Base and Length of the Rx Descriptor Ring
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	rdba = rx_ring->dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	ew32(RDBAL(0), (rdba & DMA_BIT_MASK(32)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	ew32(RDBAH(0), (rdba >> 32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	ew32(RDLEN(0), rdlen);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	ew32(RDH(0), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	ew32(RDT(0), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	rx_ring->head = adapter->hw.hw_addr + E1000_RDH(0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	rx_ring->tail = adapter->hw.hw_addr + E1000_RDT(0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	/* Enable Receive Checksum Offload for TCP and UDP */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	rxcsum = er32(RXCSUM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	if (adapter->netdev->features & NETIF_F_RXCSUM)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
		rxcsum |= E1000_RXCSUM_TUOFL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
		rxcsum &= ~E1000_RXCSUM_TUOFL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	ew32(RXCSUM, rxcsum);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	/* With jumbo frames, excessive C-state transition latencies result
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	 * in dropped transactions.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
		u32 lat =
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		    ((er32(PBA) & E1000_PBA_RXA_MASK) * 1024 -
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		     adapter->max_frame_size) * 8 / 1000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
		if (adapter->flags & FLAG_IS_ICH) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
			u32 rxdctl = er32(RXDCTL(0));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
			ew32(RXDCTL(0), rxdctl | 0x3);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		pm_qos_update_request(&adapter->netdev->pm_qos_req, lat);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		pm_qos_update_request(&adapter->netdev->pm_qos_req,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
				      PM_QOS_DEFAULT_VALUE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	/* Enable Receives */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
 * e1000e_write_mc_addr_list - write multicast addresses to MTA
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
 * Writes multicast address list to the MTA hash table.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
 * Returns: -ENOMEM on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
 *                0 on no addresses written
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
 *                X on writing X addresses to MTA
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
static int e1000e_write_mc_addr_list(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
	struct netdev_hw_addr *ha;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	u8 *mta_list;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	if (netdev_mc_empty(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
		/* nothing to program, so clear mc list */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
		hw->mac.ops.update_mc_addr_list(hw, NULL, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	mta_list = kzalloc(netdev_mc_count(netdev) * ETH_ALEN, GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	if (!mta_list)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
	/* update_mc_addr_list expects a packed array of only addresses. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	netdev_for_each_mc_addr(ha, netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	    memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	hw->mac.ops.update_mc_addr_list(hw, mta_list, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	kfree(mta_list);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	return netdev_mc_count(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
 * e1000e_write_uc_addr_list - write unicast addresses to RAR table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
 * Writes unicast address list to the RAR table.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
 * Returns: -ENOMEM on failure/insufficient address space
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
 *                0 on no addresses written
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
 *                X on writing X addresses to the RAR table
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
static int e1000e_write_uc_addr_list(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	unsigned int rar_entries = hw->mac.rar_entry_count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	int count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	/* save a rar entry for our hardware address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	rar_entries--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	/* save a rar entry for the LAA workaround */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
		rar_entries--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	/* return ENOMEM indicating insufficient memory for addresses */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	if (netdev_uc_count(netdev) > rar_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	if (!netdev_uc_empty(netdev) && rar_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		struct netdev_hw_addr *ha;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
		/* write the addresses in reverse order to avoid write
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
		 * combining
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
		netdev_for_each_uc_addr(ha, netdev) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
			if (!rar_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
			hw->mac.ops.rar_set(hw, ha->addr, rar_entries--);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
			count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	/* zero out the remaining RAR entries not used above */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	for (; rar_entries > 0; rar_entries--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
		ew32(RAH(rar_entries), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
		ew32(RAL(rar_entries), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	return count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
 * e1000e_set_rx_mode - secondary unicast, Multicast and Promiscuous mode set
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
 * The ndo_set_rx_mode entry point is called whenever the unicast or multicast
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
 * address list or the network interface flags are updated.  This routine is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
 * responsible for configuring the hardware for proper unicast, multicast,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
 * promiscuous mode, and all-multi behavior.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
static void e1000e_set_rx_mode(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	u32 rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	/* Check for Promiscuous and All Multicast modes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	/* clear the affected bits */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	if (netdev->flags & IFF_PROMISC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		/* Do not hardware filter VLANs in promisc mode */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		e1000e_vlan_filter_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
		int count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
		if (netdev->flags & IFF_ALLMULTI) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
			rctl |= E1000_RCTL_MPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
			/* Write addresses to the MTA, if the attempt fails
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
			 * then we should just turn on promiscuous mode so
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
			 * that we can at least receive multicast traffic
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
			count = e1000e_write_mc_addr_list(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
			if (count < 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
				rctl |= E1000_RCTL_MPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
		e1000e_vlan_filter_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
		/* Write addresses to available RAR registers, if there is not
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		 * sufficient space to store all the addresses then enable
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
		 * unicast promiscuous mode
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		count = e1000e_write_uc_addr_list(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
		if (count < 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
			rctl |= E1000_RCTL_UPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		e1000e_vlan_strip_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
		e1000e_vlan_strip_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
static void e1000e_setup_rss_hash(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	u32 mrqc, rxcsum;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	static const u32 rsskey[10] = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
		0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	/* Fill out hash function seed */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	for (i = 0; i < 10; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
		ew32(RSSRK(i), rsskey[i]);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	/* Direct all traffic to queue 0 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	for (i = 0; i < 32; i++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
		ew32(RETA(i), 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	/* Disable raw packet checksumming so that RSS hash is placed in
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	 * descriptor on writeback.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	rxcsum = er32(RXCSUM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	rxcsum |= E1000_RXCSUM_PCSD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	ew32(RXCSUM, rxcsum);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	mrqc = (E1000_MRQC_RSS_FIELD_IPV4 |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
		E1000_MRQC_RSS_FIELD_IPV4_TCP |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
		E1000_MRQC_RSS_FIELD_IPV6 |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		E1000_MRQC_RSS_FIELD_IPV6_TCP |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	ew32(MRQC, mrqc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
 * e1000e_get_base_timinca - get default SYSTIM time increment attributes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
 * @timinca: pointer to returned time increment attributes
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
 * Get attributes for incrementing the System Time Register SYSTIML/H at
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
 * the default base frequency, and set the cyclecounter shift value.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	u32 incvalue, incperiod, shift;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	/* Make sure clock is enabled on I217 before checking the frequency */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	if ((hw->mac.type == e1000_pch_lpt) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	    !(er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_ENABLED) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	    !(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_ENABLED)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
		u32 fextnvm7 = er32(FEXTNVM7);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
		if (!(fextnvm7 & (1 << 0))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
			ew32(FEXTNVM7, fextnvm7 | (1 << 0));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
			e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	switch (hw->mac.type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	case e1000_pch2lan:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	case e1000_pch_lpt:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
		/* On I217, the clock frequency is 25MHz or 96MHz as
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
		 * indicated by the System Clock Frequency Indication
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		if ((hw->mac.type != e1000_pch_lpt) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		    (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
			/* Stable 96MHz frequency */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
			incperiod = INCPERIOD_96MHz;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
			incvalue = INCVALUE_96MHz;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
			shift = INCVALUE_SHIFT_96MHz;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
			adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHz;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		/* fall-through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	case e1000_82574:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	case e1000_82583:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		/* Stable 25MHz frequency */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		incperiod = INCPERIOD_25MHz;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		incvalue = INCVALUE_25MHz;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		shift = INCVALUE_SHIFT_25MHz;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		adapter->cc.shift = shift;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	*timinca = ((incperiod << E1000_TIMINCA_INCPERIOD_SHIFT) |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
		    ((incvalue << shift) & E1000_TIMINCA_INCVALUE_MASK));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
 * e1000e_config_hwtstamp - configure the hwtstamp registers and enable/disable
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
 * Outgoing time stamping can be enabled and disabled. Play nice and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
 * disable it when requested, although it shouldn't cause any overhead
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
 * when no packet needs it. At most one packet in the queue may be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
 * marked for time stamping, otherwise it would be impossible to tell
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
 * for sure to which packet the hardware time stamp belongs.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
 * Incoming time stamping has to be configured via the hardware filters.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
 * Not all combinations are supported, in particular event type has to be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
 * specified. Matching the kind of event packet is not supported, with the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
 * exception of "all V2 events regardless of level 2 or 4".
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
static int e1000e_config_hwtstamp(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	struct hwtstamp_config *config = &adapter->hwtstamp_config;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	u32 rxmtrl = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	u16 rxudp = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	bool is_l4 = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	bool is_l2 = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	u32 regval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	/* flags reserved for future extensions - must be zero */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	if (config->flags)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
	switch (config->tx_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	case HWTSTAMP_TX_OFF:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
		tsync_tx_ctl = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
	case HWTSTAMP_TX_ON:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
		return -ERANGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	switch (config->rx_filter) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	case HWTSTAMP_FILTER_NONE:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		tsync_rx_ctl = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		rxmtrl = E1000_RXMTRL_PTP_V1_SYNC_MESSAGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
		is_l4 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
		rxmtrl = E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
		is_l4 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
		/* Also time stamps V2 L2 Path Delay Request/Response */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
		rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
		is_l2 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
		/* Also time stamps V2 L2 Path Delay Request/Response. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
		rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		is_l2 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
		/* Hardware cannot filter just V2 L4 Sync messages;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
		 * fall-through to V2 (both L2 and L4) Sync.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
		/* Also time stamps V2 Path Delay Request/Response. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		is_l2 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		is_l4 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
		/* Hardware cannot filter just V2 L4 Delay Request messages;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		 * fall-through to V2 (both L2 and L4) Delay Request.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
		/* Also time stamps V2 Path Delay Request/Response. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		is_l2 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		is_l4 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		/* Hardware cannot filter just V2 L4 or L2 Event messages;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		 * fall-through to all V2 (both L2 and L4) Events.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		is_l2 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		is_l4 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
		/* For V1, the hardware can only filter Sync messages or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
		 * Delay Request messages but not both so fall-through to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
		 * time stamp all packets.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	case HWTSTAMP_FILTER_ALL:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
		is_l2 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
		is_l4 = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
		config->rx_filter = HWTSTAMP_FILTER_ALL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
		return -ERANGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	/* enable/disable Tx h/w time stamping */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	regval = er32(TSYNCTXCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	regval &= ~E1000_TSYNCTXCTL_ENABLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	regval |= tsync_tx_ctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
	ew32(TSYNCTXCTL, regval);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	if ((er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_ENABLED) !=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	    (regval & E1000_TSYNCTXCTL_ENABLED)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		e_err("Timesync Tx Control register not set as expected\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
		return -EAGAIN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
	/* enable/disable Rx h/w time stamping */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
	regval = er32(TSYNCRXCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	regval &= ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	regval |= tsync_rx_ctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	ew32(TSYNCRXCTL, regval);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
	if ((er32(TSYNCRXCTL) & (E1000_TSYNCRXCTL_ENABLED |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
				 E1000_TSYNCRXCTL_TYPE_MASK)) !=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
	    (regval & (E1000_TSYNCRXCTL_ENABLED |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
		       E1000_TSYNCRXCTL_TYPE_MASK))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
		e_err("Timesync Rx Control register not set as expected\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
		return -EAGAIN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
	/* L2: define ethertype filter for time stamped packets */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	if (is_l2)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
		rxmtrl |= ETH_P_1588;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	/* define which PTP packets get time stamped */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	ew32(RXMTRL, rxmtrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	/* Filter by destination port */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	if (is_l4) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
		rxudp = PTP_EV_PORT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
		cpu_to_be16s(&rxudp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	ew32(RXUDP, rxudp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	/* Clear TSYNCRXCTL_VALID & TSYNCTXCTL_VALID bit */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	er32(RXSTMPH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	er32(TXSTMPH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	/* Get and set the System Time Register SYSTIM base frequency */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	ret_val = e1000e_get_base_timinca(adapter, &regval);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	ew32(TIMINCA, regval);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	/* reset the ns time counter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
	timecounter_init(&adapter->tc, &adapter->cc,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
			 ktime_to_ns(ktime_get_real()));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
 * e1000_configure - configure the hardware for Rx and Tx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
 * @adapter: private board structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
static void e1000_configure(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	struct e1000_ring *rx_ring = adapter->rx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	e1000e_set_rx_mode(adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	e1000_restore_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	e1000_init_manageability_pt(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	e1000_configure_tx(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	if (adapter->netdev->features & NETIF_F_RXHASH)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
		e1000e_setup_rss_hash(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	e1000_setup_rctl(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	e1000_configure_rx(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
 * e1000e_power_up_phy - restore link in case the phy was powered down
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
 * @adapter: address of board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
 * The phy may be powered down to save power and turn off link when the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
 * driver is unloaded and wake on lan is not enabled (among others)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
 * *** this routine MUST be followed by a call to e1000e_reset ***
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
void e1000e_power_up_phy(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	if (adapter->hw.phy.ops.power_up)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
		adapter->hw.phy.ops.power_up(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	adapter->hw.mac.ops.setup_link(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
 * e1000_power_down_phy - Power down the PHY
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
 * Power down the PHY so no link is implied when interface is down.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
 * The PHY cannot be powered down if management or WoL is active.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
static void e1000_power_down_phy(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	/* WoL is enabled */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	if (adapter->wol)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	if (adapter->hw.phy.ops.power_down)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		adapter->hw.phy.ops.power_down(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
 * e1000e_reset - bring the hardware into a known good state
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
 * This function boots the hardware and enables some settings that
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
 * require a configuration cycle of the hardware - those cannot be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
 * set/changed during runtime. After reset the device needs to be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
 * properly configured for Rx, Tx etc.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
void e1000e_reset(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
	struct e1000_mac_info *mac = &adapter->hw.mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
	struct e1000_fc_info *fc = &adapter->hw.fc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
	u32 tx_space, min_tx_space, min_rx_space;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	u32 pba = adapter->pba;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	u16 hwm;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
	/* reset Packet Buffer Allocation to default */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	ew32(PBA, pba);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
		/* To maintain wire speed transmits, the Tx FIFO should be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
		 * large enough to accommodate two full transmit packets,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		 * the Rx FIFO should be large enough to accommodate at least
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		 * one full receive packet and is similarly rounded up and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		 * expressed in KB.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		pba = er32(PBA);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		/* upper 16 bits has Tx packet buffer allocation size in KB */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
		tx_space = pba >> 16;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		/* lower 16 bits has Rx packet buffer allocation size in KB */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		pba &= 0xffff;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		/* the Tx fifo also stores 16 bytes of information about the Tx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		 * but don't include ethernet FCS because hardware appends it
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
		min_tx_space = (adapter->max_frame_size +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
				sizeof(struct e1000_tx_desc) - ETH_FCS_LEN) * 2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
		min_tx_space = ALIGN(min_tx_space, 1024);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		min_tx_space >>= 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		/* software strips receive CRC, so leave room for it */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		min_rx_space = adapter->max_frame_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
		min_rx_space = ALIGN(min_rx_space, 1024);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
		min_rx_space >>= 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
		/* If current Tx allocation is less than the min Tx FIFO size,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		 * and the min Tx FIFO size is less than the current Rx FIFO
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		 * allocation, take space away from current Rx allocation
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
		if ((tx_space < min_tx_space) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
		    ((min_tx_space - tx_space) < pba)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
			pba -= min_tx_space - tx_space;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
			/* if short on Rx space, Rx wins and must trump Tx
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
			 * adjustment
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
			if (pba < min_rx_space)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
				pba = min_rx_space;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
		ew32(PBA, pba);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	/* flow control settings
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
	 * The high water mark must be low enough to fit one full frame
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	 * (or the size used for early receive) above it in the Rx FIFO.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	 * Set it to the lower of:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	 * - 90% of the Rx FIFO size, and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	 * - the full Rx FIFO size minus one full frame
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
		fc->pause_time = 0xFFFF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
		fc->pause_time = E1000_FC_PAUSE_TIME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	fc->send_xon = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	fc->current_mode = fc->requested_mode;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	switch (hw->mac.type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
	case e1000_ich9lan:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
	case e1000_ich10lan:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
			pba = 14;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
			ew32(PBA, pba);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
			fc->high_water = 0x2800;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
			fc->low_water = fc->high_water - 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		/* fall-through */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		hwm = min(((pba << 10) * 9 / 10),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
			  ((pba << 10) - adapter->max_frame_size));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		fc->low_water = fc->high_water - 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
	case e1000_pchlan:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		/* Workaround PCH LOM adapter hangs with certain network
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
		 * loads.  If hangs persist, try disabling Tx flow control.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
			fc->high_water = 0x3500;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
			fc->low_water  = 0x1500;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
			fc->high_water = 0x5000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
			fc->low_water  = 0x3000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		fc->refresh_time = 0x1000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
	case e1000_pch2lan:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	case e1000_pch_lpt:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
		fc->refresh_time = 0x0400;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
		if (adapter->netdev->mtu <= ETH_DATA_LEN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
			fc->high_water = 0x05C20;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
			fc->low_water = 0x05048;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
			fc->pause_time = 0x0650;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
		fc->high_water = ((pba << 10) * 9 / 10) & E1000_FCRTH_RTH;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
		fc->low_water = ((pba << 10) * 8 / 10) & E1000_FCRTL_RTL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	/* Alignment of Tx data is on an arbitrary byte boundary with the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	 * maximum size per Tx descriptor limited only to the transmit
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	 * allocation of the packet buffer minus 96 bytes with an upper
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	 * limit of 24KB due to receive synchronization limitations.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
				       24 << 10);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
	/* Disable Adaptive Interrupt Moderation if 2 full packets cannot
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	 * fit in receive buffer.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	if (adapter->itr_setting & 0x3) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
		if ((adapter->max_frame_size * 2) > (pba << 10)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
			if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
				dev_info(&adapter->pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
					 "Interrupt Throttle Rate off\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
				adapter->flags2 |= FLAG2_DISABLE_AIM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
				e1000e_write_itr(adapter, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		} else if (adapter->flags2 & FLAG2_DISABLE_AIM) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
			dev_info(&adapter->pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
				 "Interrupt Throttle Rate on\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
			adapter->flags2 &= ~FLAG2_DISABLE_AIM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
			adapter->itr = 20000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
			e1000e_write_itr(adapter, adapter->itr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	/* Allow time for pending master requests to run */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	mac->ops.reset_hw(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	/* For parts with AMT enabled, let the firmware know
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	 * that the network interface is in control
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	if (adapter->flags & FLAG_HAS_AMT)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		e1000e_get_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	ew32(WUC, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	if (mac->ops.init_hw(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		e_err("Hardware Error\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	e1000_update_mng_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	ew32(VET, ETH_P_8021Q);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
	e1000e_reset_adaptive(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
	/* initialize systim and reset the ns time counter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	e1000e_config_hwtstamp(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	/* Set EEE advertisement as appropriate */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	if (adapter->flags2 & FLAG2_HAS_EEE) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
		s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
		u16 adv_addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
		switch (hw->phy.type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		case e1000_phy_82579:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
			adv_addr = I82579_EEE_ADVERTISEMENT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
		case e1000_phy_i217:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
			adv_addr = I217_EEE_ADVERTISEMENT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
		default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
			dev_err(&adapter->pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
				"Invalid PHY type setting EEE advertisement\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
			return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
		ret_val = hw->phy.ops.acquire(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		if (ret_val) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
			dev_err(&adapter->pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
				"EEE advertisement - unable to acquire PHY\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
			return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		e1000_write_emi_reg_locked(hw, adv_addr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
					   hw->dev_spec.ich8lan.eee_disable ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
					   0 : adapter->eee_advert);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		hw->phy.ops.release(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
	if (!netif_running(adapter->netdev) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
	    !test_bit(__E1000_TESTING, &adapter->state)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
		e1000_power_down_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
	e1000_get_phy_info(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
		u16 phy_data = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
		/* speed up time to link by disabling smart power down, ignore
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		 * the return value of this function because there is nothing
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		 * different we would do if it failed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		phy_data &= ~IGP02E1000_PM_SPD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
int e1000e_up(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	/* hardware has been reset, we need to reload some things */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	e1000_configure(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	clear_bit(__E1000_DOWN, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	if (adapter->msix_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
		e1000_configure_msix(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	netif_start_queue(adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	/* fire a link change interrupt to start the watchdog */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	if (adapter->msix_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
		ew32(ICS, E1000_ICS_LSC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
static void e1000e_flush_descriptors(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	if (!(adapter->flags2 & FLAG2_DMA_BURST))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	/* flush pending descriptor writebacks to memory */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
	/* execute the writes immediately */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	/* due to rare timing issues, write to TIDV/RDTR again to ensure the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
	 * write is successful
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
	/* execute the writes immediately */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
static void e1000e_update_stats(struct e1000_adapter *adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
void e1000e_down(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
	u32 tctl, rctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	/* signal that we're down so the interrupt handler does not
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	 * reschedule our watchdog timer
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	set_bit(__E1000_DOWN, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
	/* disable receives in the hardware */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
	rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
	/* flush and sleep below */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
	netif_stop_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
	/* disable transmits in the hardware */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
	tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
	tctl &= ~E1000_TCTL_EN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
	ew32(TCTL, tctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
	/* flush both disables and wait for them to finish */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
	usleep_range(10000, 20000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
	e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	napi_synchronize(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	del_timer_sync(&adapter->watchdog_timer);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	del_timer_sync(&adapter->phy_info_timer);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
	netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
	spin_lock(&adapter->stats64_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	e1000e_update_stats(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
	spin_unlock(&adapter->stats64_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	e1000e_flush_descriptors(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	e1000_clean_tx_ring(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	e1000_clean_rx_ring(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
	adapter->link_speed = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	adapter->link_duplex = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	if (!pci_channel_offline(adapter->pdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
		e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	/* TODO: for power management, we could drop the link and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
	 * pci_disable_device here.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
void e1000e_reinit_locked(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	might_sleep();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
		usleep_range(1000, 2000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	e1000e_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
	e1000e_up(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
	clear_bit(__E1000_RESETTING, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
 * e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
 * @cc: cyclecounter structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
	struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
						     cc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
	cycle_t systim;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
	/* latch SYSTIMH on read of SYSTIML */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	systim = (cycle_t)er32(SYSTIML);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
	systim |= (cycle_t)er32(SYSTIMH) << 32;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	return systim;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
 * @adapter: board private structure to initialize
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
 * e1000_sw_init initializes the Adapter private data structure.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
 * Fields are initialized based on PCI device information and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
 * OS network device settings (MTU size).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
static int e1000_sw_init(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
	adapter->rx_ps_bsize0 = 128;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	adapter->tx_ring_count = E1000_DEFAULT_TXD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	adapter->rx_ring_count = E1000_DEFAULT_RXD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	spin_lock_init(&adapter->stats64_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	e1000e_set_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	if (e1000_alloc_queues(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
		return -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	/* Setup hardware time stamping cyclecounter */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
		adapter->cc.read = e1000e_cyclecounter_read;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
		adapter->cc.mask = CLOCKSOURCE_MASK(64);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
		adapter->cc.mult = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
		/* cc.shift set in e1000e_get_base_tininca() */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
		spin_lock_init(&adapter->systim_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		INIT_WORK(&adapter->tx_hwtstamp_work, e1000e_tx_hwtstamp_work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
	/* Explicitly disable IRQ since the NIC can be in any state. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
	e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	set_bit(__E1000_DOWN, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
 * e1000_intr_msi_test - Interrupt Handler
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
 * @irq: interrupt number
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
 * @data: pointer to a network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
static irqreturn_t e1000_intr_msi_test(int __always_unused irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
	u32 icr = er32(ICR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	e_dbg("icr is %08X\n", icr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
	if (icr & E1000_ICR_RXSEQ) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
		/* Force memory writes to complete before acknowledging the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
		 * interrupt is handled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
		wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
 * e1000_test_msi_interrupt - Returns 0 for successful test
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
 * @adapter: board private struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
 * code flow taken from tg3.c
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
	/* poll_enable hasn't been called yet, so don't need disable */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	/* clear any pending events */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
	er32(ICR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
	/* free the real vector and request a test handler */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
	e1000_free_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
	e1000e_reset_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
	/* Assume that the test fails, if it succeeds then the test
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
	 * MSI irq handler will unset this flag
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
	adapter->flags |= FLAG_MSI_TEST_FAILED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
	err = pci_enable_msi(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		goto msi_test_failed;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
			  netdev->name, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
	if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		pci_disable_msi(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
		goto msi_test_failed;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
	/* Force memory writes to complete before enabling and firing an
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
	 * interrupt.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
	wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
	e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	/* fire an unusual interrupt on the test handler */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	ew32(ICS, E1000_ICS_RXSEQ);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
	e1e_flush();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	msleep(100);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	e1000_irq_disable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	rmb();			/* read flags after interrupt has been fired */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		e_info("MSI interrupt test failed, using legacy interrupt.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
		e_dbg("MSI interrupt test succeeded!\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
	free_irq(adapter->pdev->irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
	pci_disable_msi(adapter->pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
msi_test_failed:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
	e1000e_set_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
	return e1000_request_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
 * @adapter: board private struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
 * code flow taken from tg3.c, called with e1000 interrupts disabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
static int e1000_test_msi(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	u16 pci_cmd;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	if (!(adapter->flags & FLAG_MSI_ENABLED))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	/* disable SERR in case the MSI write causes a master abort */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
	if (pci_cmd & PCI_COMMAND_SERR)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
		pci_write_config_word(adapter->pdev, PCI_COMMAND,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
				      pci_cmd & ~PCI_COMMAND_SERR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	err = e1000_test_msi_interrupt(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
	/* re-enable SERR */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	if (pci_cmd & PCI_COMMAND_SERR) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
		pci_cmd |= PCI_COMMAND_SERR;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
		pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
 * e1000_open - Called when a network interface is made active
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
 * Returns 0 on success, negative value on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
 * The open entry point is called when a network interface is made
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
 * active by the system (IFF_UP).  At this point all resources needed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
 * for transmit and receive operations are allocated, the interrupt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
 * handler is registered with the OS, the watchdog timer is started,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
 * and the stack is notified that the interface is ready.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
static int e1000_open(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
	/* disallow open during test */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	if (test_bit(__E1000_TESTING, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	pm_runtime_get_sync(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	/* allocate transmit descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	err = e1000e_setup_tx_resources(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
		goto err_setup_tx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	/* allocate receive descriptors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	err = e1000e_setup_rx_resources(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
		goto err_setup_rx;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
	/* If AMT is enabled, let the firmware know that the network
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	 * interface is now open and reset the part to a known state.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	if (adapter->flags & FLAG_HAS_AMT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		e1000e_get_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
		e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
	e1000e_power_up_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	if ((adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		e1000_update_mng_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	/* DMA latency requirement to workaround jumbo issue */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
	pm_qos_add_request(&adapter->netdev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
			   PM_QOS_DEFAULT_VALUE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	/* before we allocate an interrupt, we must be ready to handle it.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
	 * as soon as we call pci_request_irq, so we have to setup our
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
	 * clean_rx handler before we do so.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
	e1000_configure(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
	err = e1000_request_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
		goto err_req_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
	/* Work around PCIe errata with MSI interrupts causing some chipsets to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	 * ignore e1000e MSI messages, which means we need to test our MSI
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	 * interrupt now
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
		err = e1000_test_msi(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
		if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
			e_err("Interrupt allocation failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
			goto err_req_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	/* From here on the code is the same as e1000e_up() */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
	clear_bit(__E1000_DOWN, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
	napi_enable(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
	e1000_irq_enable(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
	adapter->tx_hang_recheck = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
	netif_start_queue(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
	adapter->idle_check = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
	hw->mac.get_link_status = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	pm_runtime_put(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
	/* fire a link status change interrupt to start the watchdog */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	if (adapter->msix_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
		ew32(ICS, E1000_ICS_LSC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
err_req_irq:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
	e1000e_release_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	e1000_power_down_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
	e1000e_free_rx_resources(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
err_setup_rx:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
	e1000e_free_tx_resources(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
err_setup_tx:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
	pm_runtime_put_sync(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
 * e1000_close - Disables a network interface
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
 * Returns 0, this is not allowed to fail
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
 * The close entry point is called when an interface is de-activated
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
 * by the OS.  The hardware is still under the drivers control, but
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
 * needs to be disabled.  A global MAC reset is issued to stop the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
 * hardware, and all transmit and receive resources are freed.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
static int e1000_close(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	int count = E1000_CHECK_RESET_COUNT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		usleep_range(10000, 20000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	pm_runtime_get_sync(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	if (!test_bit(__E1000_DOWN, &adapter->state)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
		e1000e_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
		e1000_free_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	napi_disable(&adapter->napi);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	e1000_power_down_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
	e1000e_free_tx_resources(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
	e1000e_free_rx_resources(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
	/* kill manageability vlan ID if supported, but not if a vlan with
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	 * the same ID is registered on the host OS (let 8021q kill it)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
	if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
				       adapter->mng_vlan_id);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	/* If AMT is enabled, let the firmware know that the network
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	 * interface is now closed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	if ((adapter->flags & FLAG_HAS_AMT) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	    !test_bit(__E1000_TESTING, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
		e1000e_release_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	pm_qos_remove_request(&adapter->netdev->pm_qos_req);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	pm_runtime_put_sync(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
 * e1000_set_mac - Change the Ethernet Address of the NIC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
 * @p: pointer to an address structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
static int e1000_set_mac(struct net_device *netdev, void *p)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	struct sockaddr *addr = p;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	if (!is_valid_ether_addr(addr->sa_data))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
		return -EADDRNOTAVAIL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
		/* activate the work around */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
		e1000e_set_laa_state_82571(&adapter->hw, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
		/* Hold a copy of the LAA in RAR[14] This is done so that
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		 * between the time RAR[0] gets clobbered  and the time it
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		 * of the RARs and no incoming packets directed to this port
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		 * are dropped. Eventually the LAA will be in RAR[0] and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		 * RAR[14]
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
				    adapter->hw.mac.rar_entry_count - 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
 * e1000e_update_phy_task - work thread to update phy
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
 * @work: pointer to our work struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
 * this worker thread exists because we must acquire a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
 * semaphore to read the phy, which we could msleep while
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
 * waiting for it, and we can't msleep in a timer.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
static void e1000e_update_phy_task(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	struct e1000_adapter *adapter = container_of(work,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
						     struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
						     update_phy_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	if (test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	e1000_get_phy_info(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
 * e1000_update_phy_info - timre call-back to update PHY info
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
 * @data: pointer to adapter cast into an unsigned long
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
 * Need to wait a few seconds after link up to get diagnostic information from
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
 * the phy
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
static void e1000_update_phy_info(unsigned long data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
	if (test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	schedule_work(&adapter->update_phy_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
 * e1000e_update_phy_stats - Update the PHY statistics counters
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
 * Read/clear the upper 16-bit PHY registers and read/accumulate lower
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
static void e1000e_update_phy_stats(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
	s32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	u16 phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	ret_val = hw->phy.ops.acquire(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
	/* A page set is expensive so check if already on desired page.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	 * If not, set to the page with the PHY status registers.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
	hw->phy.addr = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
					   &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		goto release;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
	if (phy_data != (HV_STATS_PAGE << IGP_PAGE_SHIFT)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
		ret_val = hw->phy.ops.set_page(hw,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
					       HV_STATS_PAGE << IGP_PAGE_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
			goto release;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	/* Single Collision Count */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
	ret_val = hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
	if (!ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		adapter->stats.scc += phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	/* Excessive Collision Count */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
	ret_val = hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	if (!ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
		adapter->stats.ecol += phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	/* Multiple Collision Count */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
	hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	ret_val = hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	if (!ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
		adapter->stats.mcc += phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	/* Late Collision Count */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	ret_val = hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
	if (!ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		adapter->stats.latecol += phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	/* Collision Count - also used for adaptive IFS */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
	hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
	ret_val = hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	if (!ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
		hw->mac.collision_delta = phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	/* Defer Count */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	ret_val = hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	if (!ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
		adapter->stats.dc += phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	/* Transmit with no CRS */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	ret_val = hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	if (!ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
		adapter->stats.tncrs += phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
release:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
	hw->phy.ops.release(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
 * e1000e_update_stats - Update the board statistics counters
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
static void e1000e_update_stats(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	/* Prevent stats update while adapter is being reset, or if the pci
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	 * connection is down.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	if (adapter->link_speed == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	if (pci_channel_offline(pdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	adapter->stats.crcerrs += er32(CRCERRS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	adapter->stats.gprc += er32(GPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	adapter->stats.gorc += er32(GORCL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	er32(GORCH); /* Clear gorc */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	adapter->stats.bprc += er32(BPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	adapter->stats.mprc += er32(MPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
	adapter->stats.roc += er32(ROC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
	adapter->stats.mpc += er32(MPC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	/* Half-duplex statistics */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	if (adapter->link_duplex == HALF_DUPLEX) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		if (adapter->flags2 & FLAG2_HAS_PHY_STATS) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
			e1000e_update_phy_stats(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
			adapter->stats.scc += er32(SCC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
			adapter->stats.ecol += er32(ECOL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
			adapter->stats.mcc += er32(MCC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
			adapter->stats.latecol += er32(LATECOL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
			adapter->stats.dc += er32(DC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
			hw->mac.collision_delta = er32(COLC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
			if ((hw->mac.type != e1000_82574) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
			    (hw->mac.type != e1000_82583))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
				adapter->stats.tncrs += er32(TNCRS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
		adapter->stats.colc += hw->mac.collision_delta;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
	adapter->stats.xonrxc += er32(XONRXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	adapter->stats.xontxc += er32(XONTXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	adapter->stats.xoffrxc += er32(XOFFRXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	adapter->stats.xofftxc += er32(XOFFTXC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	adapter->stats.gptc += er32(GPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	adapter->stats.gotc += er32(GOTCL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	er32(GOTCH); /* Clear gotc */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	adapter->stats.rnbc += er32(RNBC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	adapter->stats.ruc += er32(RUC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	adapter->stats.mptc += er32(MPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	adapter->stats.bptc += er32(BPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	/* used for adaptive IFS */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	hw->mac.tx_packet_delta = er32(TPT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	adapter->stats.tpt += hw->mac.tx_packet_delta;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	adapter->stats.algnerrc += er32(ALGNERRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	adapter->stats.rxerrc += er32(RXERRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	adapter->stats.cexterr += er32(CEXTERR);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
	adapter->stats.tsctc += er32(TSCTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	adapter->stats.tsctfc += er32(TSCTFC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	/* Fill out the OS statistics structure */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
	netdev->stats.multicast = adapter->stats.mprc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	netdev->stats.collisions = adapter->stats.colc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	/* Rx Errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	/* RLEC on some newer hardware can be incorrect so build
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
	 * our own version based on RUC and ROC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
	netdev->stats.rx_errors = adapter->stats.rxerrc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
	    adapter->stats.crcerrs + adapter->stats.algnerrc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	    adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
	netdev->stats.rx_length_errors = adapter->stats.ruc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
	    adapter->stats.roc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	/* Tx Errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	netdev->stats.tx_errors = adapter->stats.ecol + adapter->stats.latecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	netdev->stats.tx_window_errors = adapter->stats.latecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	/* Tx Dropped needs to be maintained elsewhere */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	/* Management Stats */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
	adapter->stats.mgptc += er32(MGTPTC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	adapter->stats.mgprc += er32(MGTPRC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
	adapter->stats.mgpdc += er32(MGTPDC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
	/* Correctable ECC Errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
	if (hw->mac.type == e1000_pch_lpt) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
		u32 pbeccsts = er32(PBECCSTS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
		adapter->corr_errors +=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		adapter->uncorr_errors +=
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
 * e1000_phy_read_status - Update the PHY register status snapshot
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
 * @adapter: board private structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
static void e1000_phy_read_status(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	struct e1000_phy_regs *phy = &adapter->phy_regs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
	if ((er32(STATUS) & E1000_STATUS_LU) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
		int ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
		pm_runtime_get_sync(&adapter->pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
		ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
		ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
		ret_val |= e1e_rphy(hw, MII_LPA, &phy->lpa);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
		ret_val |= e1e_rphy(hw, MII_EXPANSION, &phy->expansion);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
		ret_val |= e1e_rphy(hw, MII_CTRL1000, &phy->ctrl1000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
		ret_val |= e1e_rphy(hw, MII_STAT1000, &phy->stat1000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
		ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
		if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
			e_warn("Error reading PHY register\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
		pm_runtime_put_sync(&adapter->pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
		/* Do not read PHY registers if link is not up
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
		 * Set values to typical power-on defaults
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
			     BMSR_ERCAP);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
				  ADVERTISE_ALL | ADVERTISE_CSMA);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
		phy->lpa = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
		phy->expansion = EXPANSION_ENABLENPAGE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
		phy->ctrl1000 = ADVERTISE_1000FULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
		phy->stat1000 = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
static void e1000_print_link_info(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	u32 ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	/* Link status message must follow this format for user tools */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	pr_info("%s NIC Link is Up %d Mbps %s Duplex, Flow Control: %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
		adapter->netdev->name, adapter->link_speed,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
		(ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE) ? "Rx/Tx" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
		(ctrl & E1000_CTRL_RFCE) ? "Rx" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
		(ctrl & E1000_CTRL_TFCE) ? "Tx" : "None");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
static bool e1000e_has_link(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	bool link_active = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	s32 ret_val = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	/* get_link_status is set on LSC (link status) interrupt or
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	 * Rx sequence error interrupt.  get_link_status will stay
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	 * false until the check_for_link establishes link
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	 * for copper adapters ONLY
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	switch (hw->phy.media_type) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	case e1000_media_type_copper:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
		if (hw->mac.get_link_status) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
			ret_val = hw->mac.ops.check_for_link(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
			link_active = !hw->mac.get_link_status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
			link_active = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	case e1000_media_type_fiber:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
		ret_val = hw->mac.ops.check_for_link(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
	case e1000_media_type_internal_serdes:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
		ret_val = hw->mac.ops.check_for_link(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
		link_active = adapter->hw.mac.serdes_has_link;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
	case e1000_media_type_unknown:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
		e_info("Gigabit has been disabled, downgrading speed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	return link_active;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
static void e1000e_enable_receives(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
	/* make sure the receive unit is started */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	    (adapter->flags & FLAG_RESTART_NOW)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
		struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
		u32 rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
		ew32(RCTL, rctl | E1000_RCTL_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
		adapter->flags &= ~FLAG_RESTART_NOW;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	/* With 82574 controllers, PHY needs to be checked periodically
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	 * for hung state and reset, if two calls return true
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
	if (e1000_check_phy_82574(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
		adapter->phy_hang_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
		adapter->phy_hang_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	if (adapter->phy_hang_count > 1) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
		adapter->phy_hang_count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
		schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
 * e1000_watchdog - Timer Call-back
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
 * @data: pointer to adapter cast into an unsigned long
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
static void e1000_watchdog(unsigned long data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
	/* Do the rest outside of interrupt context */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	schedule_work(&adapter->watchdog_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
	/* TODO: make this use queue_delayed_work() */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
static void e1000_watchdog_task(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	struct e1000_adapter *adapter = container_of(work,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
						     struct e1000_adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
						     watchdog_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	struct e1000_mac_info *mac = &adapter->hw.mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	struct e1000_phy_info *phy = &adapter->hw.phy;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	struct e1000_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
	u32 link, tctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
	if (test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
	link = e1000e_has_link(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
	if ((netif_carrier_ok(netdev)) && link) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		/* Cancel scheduled suspend requests. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		pm_runtime_resume(netdev->dev.parent);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
		e1000e_enable_receives(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
		goto link_up;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
		e1000_update_mng_vlan(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
	if (link) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
		if (!netif_carrier_ok(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
			bool txb2b = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
			/* Cancel scheduled suspend requests. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
			pm_runtime_resume(netdev->dev.parent);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
			/* update snapshot of PHY registers on LSC */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
			e1000_phy_read_status(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
			mac->ops.get_link_up_info(&adapter->hw,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
						  &adapter->link_speed,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
						  &adapter->link_duplex);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
			e1000_print_link_info(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
			/* check if SmartSpeed worked */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
			e1000e_check_downshift(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
			if (phy->speed_downgraded)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
				netdev_warn(netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
					    "Link Speed was downgraded by SmartSpeed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
			/* On supported PHYs, check for duplex mismatch only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
			 * if link has autonegotiated at 10/100 half
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
			if ((hw->phy.type == e1000_phy_igp_3 ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
			     hw->phy.type == e1000_phy_bm) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
			    (hw->mac.autoneg == true) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
			    (adapter->link_speed == SPEED_10 ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
			     adapter->link_speed == SPEED_100) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
			    (adapter->link_duplex == HALF_DUPLEX)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
				u16 autoneg_exp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
				e1e_rphy(hw, MII_EXPANSION, &autoneg_exp);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
				if (!(autoneg_exp & EXPANSION_NWAY))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
					e_info("Autonegotiated half duplex but link partner cannot autoneg.  Try forcing full duplex if link gets many collisions.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
			/* adjust timeout factor according to speed/duplex */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
			adapter->tx_timeout_factor = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
			switch (adapter->link_speed) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
			case SPEED_10:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
				txb2b = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
				adapter->tx_timeout_factor = 16;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
			case SPEED_100:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
				txb2b = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
				adapter->tx_timeout_factor = 10;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
				break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
			/* workaround: re-program speed mode bit after
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
			 * link-up event
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
			    !txb2b) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
				u32 tarc0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
				tarc0 = er32(TARC(0));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
				tarc0 &= ~SPEED_MODE_BIT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
				ew32(TARC(0), tarc0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
			/* disable TSO for pcie and 10/100 speeds, to avoid
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
			 * some hardware issues
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
				switch (adapter->link_speed) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
				case SPEED_10:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
				case SPEED_100:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
					e_info("10/100 speed: disabling TSO\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
					netdev->features &= ~NETIF_F_TSO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
					netdev->features &= ~NETIF_F_TSO6;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
					break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
				case SPEED_1000:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
					netdev->features |= NETIF_F_TSO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
					netdev->features |= NETIF_F_TSO6;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
					break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
				default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
					/* oops */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
					break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
				}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
			/* enable transmits in the hardware, need to do this
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
			 * after setting TARC(0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
			tctl = er32(TCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
			tctl |= E1000_TCTL_EN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
			ew32(TCTL, tctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
			/* Perform any post-link-up configuration before
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
			 * reporting link up.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
			if (phy->ops.cfg_on_link_up)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
				phy->ops.cfg_on_link_up(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
			netif_carrier_on(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
			if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
				mod_timer(&adapter->phy_info_timer,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
					  round_jiffies(jiffies + 2 * HZ));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
		if (netif_carrier_ok(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
			adapter->link_speed = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
			adapter->link_duplex = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
			/* Link status message must follow this format */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
			pr_info("%s NIC Link is Down\n", adapter->netdev->name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
			netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
			if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
				mod_timer(&adapter->phy_info_timer,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
					  round_jiffies(jiffies + 2 * HZ));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
			/* The link is lost so the controller stops DMA.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
			 * If there is queued Tx work that cannot be done
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
			 * or if on an 8000ES2LAN which requires a Rx packet
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
			 * buffer work-around on link down event, reset the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
			 * controller to flush the Tx/Rx packet buffers.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
			 * (Do the reset outside of interrupt context).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
			if ((adapter->flags & FLAG_RX_NEEDS_RESTART) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
			    (e1000_desc_unused(tx_ring) + 1 < tx_ring->count))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
				adapter->flags |= FLAG_RESTART_NOW;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
				pm_schedule_suspend(netdev->dev.parent,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
						    LINK_TIMEOUT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
link_up:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
	spin_lock(&adapter->stats64_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
	e1000e_update_stats(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
	adapter->tpt_old = adapter->stats.tpt;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
	adapter->colc_old = adapter->stats.colc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
	adapter->gorc_old = adapter->stats.gorc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
	adapter->gotc_old = adapter->stats.gotc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
	spin_unlock(&adapter->stats64_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
	if (adapter->flags & FLAG_RESTART_NOW) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
		schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
		/* return immediately since reset is imminent */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	e1000e_update_adaptive(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	/* Simple mode for Interrupt Throttle Rate (ITR) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
	if (adapter->itr_setting == 4) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
		/* Symmetric Tx/Rx gets a reduced ITR=2000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
		 * Total asymmetrical Tx or Rx gets ITR=8000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
		 * everyone else is between 2000-8000.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
		u32 goc = (adapter->gotc + adapter->gorc) / 10000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
		u32 dif = (adapter->gotc > adapter->gorc ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
			   adapter->gotc - adapter->gorc :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
			   adapter->gorc - adapter->gotc) / 10000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
		e1000e_write_itr(adapter, itr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
	/* Cause software interrupt to ensure Rx ring is cleaned */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
	if (adapter->msix_entries)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
		ew32(ICS, adapter->rx_ring->ims_val);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
		ew32(ICS, E1000_ICS_RXDMT0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
	/* flush pending descriptors to memory before detecting Tx hang */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
	e1000e_flush_descriptors(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
	/* Force detection of hung controller every watchdog period */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	adapter->detect_tx_hung = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
	/* With 82571 controllers, LAA may be overwritten due to controller
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
	 * reset from the other port. Set the appropriate LAA in RAR[0]
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
	if (e1000e_get_laa_state_82571(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
		hw->mac.ops.rar_set(hw, adapter->hw.mac.addr, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	if (adapter->flags2 & FLAG2_CHECK_PHY_HANG)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
		e1000e_check_82574_phy_workaround(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	/* Clear valid timestamp stuck in RXSTMPL/H due to a Rx error */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
	if (adapter->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
		if ((adapter->flags2 & FLAG2_CHECK_RX_HWTSTAMP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
		    (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
			er32(RXSTMPH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
			adapter->rx_hwtstamp_cleared++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
			adapter->flags2 |= FLAG2_CHECK_RX_HWTSTAMP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	/* Reset the timer */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
	if (!test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
		mod_timer(&adapter->watchdog_timer,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
			  round_jiffies(jiffies + 2 * HZ));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
#define E1000_TX_FLAGS_CSUM		0x00000001
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
#define E1000_TX_FLAGS_VLAN		0x00000002
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
#define E1000_TX_FLAGS_TSO		0x00000004
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
#define E1000_TX_FLAGS_IPV4		0x00000008
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
#define E1000_TX_FLAGS_NO_FCS		0x00000010
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
#define E1000_TX_FLAGS_HWTSTAMP		0x00000020
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
#define E1000_TX_FLAGS_VLAN_SHIFT	16
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
	struct e1000_context_desc *context_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
	u32 cmd_length = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
	u16 ipcse = 0, mss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
	if (!skb_is_gso(skb))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	if (skb_header_cloned(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
		int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
		if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
			return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	mss = skb_shinfo(skb)->gso_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
	if (skb->protocol == htons(ETH_P_IP)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
		struct iphdr *iph = ip_hdr(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
		iph->tot_len = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
		iph->check = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
							 0, IPPROTO_TCP, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		cmd_length = E1000_TXD_CMD_IP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
		ipcse = skb_transport_offset(skb) - 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
	} else if (skb_is_gso_v6(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		ipv6_hdr(skb)->payload_len = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
						       &ipv6_hdr(skb)->daddr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
						       0, IPPROTO_TCP, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
		ipcse = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	ipcss = skb_network_offset(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
	tucss = skb_transport_offset(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
		       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
	buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
	context_desc->lower_setup.ip_fields.ipcss  = ipcss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	context_desc->lower_setup.ip_fields.ipcso  = ipcso;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
	context_desc->upper_setup.tcp_fields.tucss = tucss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	context_desc->upper_setup.tcp_fields.tucso = tucso;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
	context_desc->upper_setup.tcp_fields.tucse = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
	context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
	buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
	i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	if (i == tx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
		i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
	tx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	return 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
	struct e1000_context_desc *context_desc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
	u8 css;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
	u32 cmd_len = E1000_TXD_CMD_DEXT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
	__be16 protocol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
	if (skb->ip_summed != CHECKSUM_PARTIAL)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
		protocol = skb->protocol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
	switch (protocol) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
	case cpu_to_be16(ETH_P_IP):
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
			cmd_len |= E1000_TXD_CMD_TCP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
	case cpu_to_be16(ETH_P_IPV6):
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
		/* XXX not handling all IPV6 headers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
			cmd_len |= E1000_TXD_CMD_TCP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
		if (unlikely(net_ratelimit()))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
			e_warn("checksum_partial proto=%x!\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
			       be16_to_cpu(protocol));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
	css = skb_checksum_start_offset(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
	i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
	buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
	context_desc->lower_setup.ip_config = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
	context_desc->upper_setup.tcp_fields.tucss = css;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
	context_desc->upper_setup.tcp_fields.tucse = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
	context_desc->tcp_seg_setup.data = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
	buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
	buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
	i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
	if (i == tx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
		i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
	tx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	return 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
			unsigned int first, unsigned int max_per_txd,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
			unsigned int nr_frags)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
	struct pci_dev *pdev = adapter->pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
	unsigned int len = skb_headlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
	unsigned int offset = 0, size, count = 0, i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
	unsigned int f, bytecount, segs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
	i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
	while (len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
		size = min(len, max_per_txd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
		buffer_info->length = size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
		buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
		buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
		buffer_info->dma = dma_map_single(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
						  skb->data + offset,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
						  size, DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
		buffer_info->mapped_as_page = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
			goto dma_error;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
		len -= size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
		offset += size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
		count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
		if (len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
			i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
			if (i == tx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
				i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
	for (f = 0; f < nr_frags; f++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
		const struct skb_frag_struct *frag;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		frag = &skb_shinfo(skb)->frags[f];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
		len = skb_frag_size(frag);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
		offset = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
		while (len) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
			i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
			if (i == tx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
				i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
			buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
			size = min(len, max_per_txd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
			buffer_info->length = size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
			buffer_info->time_stamp = jiffies;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
			buffer_info->next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
							    offset, size,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
							    DMA_TO_DEVICE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
			buffer_info->mapped_as_page = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
				goto dma_error;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
			len -= size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
			offset += size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
			count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	segs = skb_shinfo(skb)->gso_segs ? : 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
	/* multiply data chunks by size of headers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	tx_ring->buffer_info[i].skb = skb;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
	tx_ring->buffer_info[i].segs = segs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
	tx_ring->buffer_info[i].bytecount = bytecount;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
	tx_ring->buffer_info[first].next_to_watch = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
	return count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
dma_error:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
	dev_err(&pdev->dev, "Tx DMA map failed\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	buffer_info->dma = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
	if (count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
		count--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	while (count--) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
		if (i == 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
			i += tx_ring->count;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
		i--;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
		e1000_put_txbuf(tx_ring, buffer_info);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
	struct e1000_tx_desc *tx_desc = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	struct e1000_buffer *buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	unsigned int i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
	if (tx_flags & E1000_TX_FLAGS_TSO) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
		    E1000_TXD_CMD_TSE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
		if (tx_flags & E1000_TX_FLAGS_IPV4)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
		txd_lower |= E1000_TXD_CMD_VLE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
		txd_lower &= ~(E1000_TXD_CMD_IFCS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
	if (unlikely(tx_flags & E1000_TX_FLAGS_HWTSTAMP)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
		txd_upper |= E1000_TXD_EXTCMD_TSTAMP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
	i = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
	do {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
		buffer_info = &tx_ring->buffer_info[i];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
		tx_desc = E1000_TX_DESC(*tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
		tx_desc->lower.data = cpu_to_le32(txd_lower |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
						  buffer_info->length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
		tx_desc->upper.data = cpu_to_le32(txd_upper);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
		i++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
		if (i == tx_ring->count)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
			i = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
	} while (--count > 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	/* Force memory writes to complete before letting h/w
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
	 * know there are new descriptors to fetch.  (Only
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
	 * applicable for weak-ordered memory model archs,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
	 * such as IA-64).
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	wmb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
	tx_ring->next_to_use = i;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
		e1000e_update_tdt_wa(tx_ring, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
		writel(i, tx_ring->tail);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
	/* we need this if more than one processor can write to our tail
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
	 * at a time, it synchronizes IO on IA64/Altix systems
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	mmiowb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
#define MINIMUM_DHCP_PACKET_SIZE 282
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
				    struct sk_buff *skb)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	struct e1000_hw *hw =  &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
	u16 length, offset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
	if (vlan_tx_tag_present(skb) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
	    !((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
	      (adapter->hw.mng_cookie.status &
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
	       E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
	if (((struct ethhdr *)skb->data)->h_proto != htons(ETH_P_IP))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
	{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
		const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data + 14);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
		struct udphdr *udp;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
		if (ip->protocol != IPPROTO_UDP)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
			return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
		if (ntohs(udp->dest) != 67)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
			return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
		offset = (u8 *)udp + 8 - skb->data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
		length = skb->len - offset;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
		return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
	struct e1000_adapter *adapter = tx_ring->adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
	netif_stop_queue(adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
	/* Herbert's original patch had:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
	 *  smp_mb__after_netif_stop_queue();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
	 * but since that doesn't exist yet, just open code it.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
	smp_mb();
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
	/* We need to check again in a case another CPU has just
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
	 * made room available.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
	if (e1000_desc_unused(tx_ring) < size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
		return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
	/* A reprieve! */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
	netif_start_queue(adapter->netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
	++adapter->restart_queue;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
	BUG_ON(size > tx_ring->count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	if (e1000_desc_unused(tx_ring) >= size)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
	return __e1000_maybe_stop_tx(tx_ring, size);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
				    struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
	struct e1000_ring *tx_ring = adapter->tx_ring;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
	unsigned int first;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
	unsigned int tx_flags = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
	unsigned int len = skb_headlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	unsigned int nr_frags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	unsigned int mss;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
	int count = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	int tso;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
	unsigned int f;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
	if (test_bit(__E1000_DOWN, &adapter->state)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
		dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
		return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
	if (skb->len <= 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
		dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
		return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
	/* The minimum packet size with TCTL.PSP set is 17 bytes so
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
	 * pad skb in order to meet this minimum size requirement
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
	if (unlikely(skb->len < 17)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
		if (skb_pad(skb, 17 - skb->len))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
			return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
		skb->len = 17;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
		skb_set_tail_pointer(skb, 17);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
	mss = skb_shinfo(skb)->gso_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
	if (mss) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
		u8 hdr_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
		 * points to just header, pull a few bytes of payload from
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
		 * frags into skb->data
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
		/* we do this workaround for ES2LAN, but it is un-necessary,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
		 * avoiding it could save a lot of cycles
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
		if (skb->data_len && (hdr_len == len)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
			unsigned int pull_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
			pull_size = min_t(unsigned int, 4, skb->data_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
			if (!__pskb_pull_tail(skb, pull_size)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
				e_err("__pskb_pull_tail failed.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
				dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
				return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
			len = skb_headlen(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
	/* reserve a descriptor for the offload context */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
		count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
	count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
	count += DIV_ROUND_UP(len, adapter->tx_fifo_limit);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
	nr_frags = skb_shinfo(skb)->nr_frags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
	for (f = 0; f < nr_frags; f++)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
		count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
				      adapter->tx_fifo_limit);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
	if (adapter->hw.mac.tx_pkt_filtering)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
		e1000_transfer_dhcp_info(adapter, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	/* need: count + 2 desc gap to keep tail from touching
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
	 * head, otherwise try next time
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
	if (e1000_maybe_stop_tx(tx_ring, count + 2))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
		return NETDEV_TX_BUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
	if (vlan_tx_tag_present(skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
		tx_flags |= E1000_TX_FLAGS_VLAN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	first = tx_ring->next_to_use;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
	tso = e1000_tso(tx_ring, skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
	if (tso < 0) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
		dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
		return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
	if (tso)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
		tx_flags |= E1000_TX_FLAGS_TSO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
	else if (e1000_tx_csum(tx_ring, skb))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
		tx_flags |= E1000_TX_FLAGS_CSUM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
	 * no longer assume, we must.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
	if (skb->protocol == htons(ETH_P_IP))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
		tx_flags |= E1000_TX_FLAGS_IPV4;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
	if (unlikely(skb->no_fcs))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
		tx_flags |= E1000_TX_FLAGS_NO_FCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	/* if count is 0 then mapping error has occurred */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
	count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
			     nr_frags);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
	if (count) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
		if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
			     !adapter->tx_hwtstamp_skb)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
			tx_flags |= E1000_TX_FLAGS_HWTSTAMP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
			adapter->tx_hwtstamp_skb = skb_get(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
			schedule_work(&adapter->tx_hwtstamp_work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
			skb_tx_timestamp(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
		netdev_sent_queue(netdev, skb->len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
		e1000_tx_queue(tx_ring, tx_flags, count);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
		/* Make sure there is space in the ring for the next send. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
		e1000_maybe_stop_tx(tx_ring,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
				    (MAX_SKB_FRAGS *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
				     DIV_ROUND_UP(PAGE_SIZE,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
						  adapter->tx_fifo_limit) + 2));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
		dev_kfree_skb_any(skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
		tx_ring->buffer_info[first].time_stamp = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
		tx_ring->next_to_use = first;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
	return NETDEV_TX_OK;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
 * e1000_tx_timeout - Respond to a Tx Hang
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
static void e1000_tx_timeout(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
	/* Do the reset outside of interrupt context */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
	adapter->tx_timeout_count++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
	schedule_work(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
static void e1000_reset_task(struct work_struct *work)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
	struct e1000_adapter *adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
	adapter = container_of(work, struct e1000_adapter, reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
	/* don't run the task if already down */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
	if (test_bit(__E1000_DOWN, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
	if (!(adapter->flags & FLAG_RESTART_NOW)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
		e1000e_dump(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
		e_err("Reset adapter unexpectedly\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
	e1000e_reinit_locked(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
 * e1000_get_stats64 - Get System Network Statistics
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
 * @stats: rtnl_link_stats64 pointer
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
 * Returns the address of the device statistics structure.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
					     struct rtnl_link_stats64 *stats)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
	memset(stats, 0, sizeof(struct rtnl_link_stats64));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
	spin_lock(&adapter->stats64_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
	e1000e_update_stats(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
	/* Fill out the OS statistics structure */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
	stats->rx_bytes = adapter->stats.gorc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
	stats->rx_packets = adapter->stats.gprc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
	stats->tx_bytes = adapter->stats.gotc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
	stats->tx_packets = adapter->stats.gptc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
	stats->multicast = adapter->stats.mprc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
	stats->collisions = adapter->stats.colc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
	/* Rx Errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
	/* RLEC on some newer hardware can be incorrect so build
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
	 * our own version based on RUC and ROC
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
	stats->rx_errors = adapter->stats.rxerrc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
	    adapter->stats.crcerrs + adapter->stats.algnerrc +
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
	    adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
	stats->rx_length_errors = adapter->stats.ruc + adapter->stats.roc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	stats->rx_crc_errors = adapter->stats.crcerrs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	stats->rx_frame_errors = adapter->stats.algnerrc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	stats->rx_missed_errors = adapter->stats.mpc;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
	/* Tx Errors */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
	stats->tx_errors = adapter->stats.ecol + adapter->stats.latecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	stats->tx_aborted_errors = adapter->stats.ecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
	stats->tx_window_errors = adapter->stats.latecol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
	stats->tx_carrier_errors = adapter->stats.tncrs;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
	/* Tx Dropped needs to be maintained elsewhere */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
	spin_unlock(&adapter->stats64_lock);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
	return stats;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
 * e1000_change_mtu - Change the Maximum Transfer Unit
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
 * @new_mtu: new value for maximum frame size
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
	/* Jumbo frame support */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
		e_err("Jumbo Frames not supported.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
	/* Supported frame sizes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
	    (max_frame > adapter->max_hw_frame_size)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
		e_err("Unsupported MTU setting\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
	/* Jumbo frame workaround on 82579 and newer requires CRC be stripped */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
	if ((adapter->hw.mac.type >= e1000_pch2lan) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
	    !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
	    (new_mtu > ETH_DATA_LEN)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
		e_err("Jumbo Frames not supported on this device when CRC stripping is disabled.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
		return -EINVAL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
		usleep_range(1000, 2000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
	adapter->max_frame_size = max_frame;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
	netdev->mtu = new_mtu;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
		e1000e_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
	 * means we reserve 2 more, this pushes us to allocate from the next
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
	 * larger slab size.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
	 * i.e. RXBUFFER_2048 --> size-4096 slab
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
	 * However with the new *_jumbo_rx* routines, jumbo receives will use
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
	 * fragmented skbs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
	if (max_frame <= 2048)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
		adapter->rx_buffer_len = 2048;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
		adapter->rx_buffer_len = 4096;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
	/* adjust allocation if LPE protects us, and we aren't using SBP */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
	    (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
		    + ETH_FCS_LEN;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
		e1000e_up(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
		e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
	clear_bit(__E1000_RESETTING, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
			   int cmd)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
	struct mii_ioctl_data *data = if_mii(ifr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
	if (adapter->hw.phy.media_type != e1000_media_type_copper)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
		return -EOPNOTSUPP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
	switch (cmd) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
	case SIOCGMIIPHY:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
		data->phy_id = adapter->hw.phy.addr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
	case SIOCGMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
		e1000_phy_read_status(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
		switch (data->reg_num & 0x1F) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
		case MII_BMCR:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
			data->val_out = adapter->phy_regs.bmcr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
		case MII_BMSR:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
			data->val_out = adapter->phy_regs.bmsr;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
		case MII_PHYSID1:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
			data->val_out = (adapter->hw.phy.id >> 16);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
		case MII_PHYSID2:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
			data->val_out = (adapter->hw.phy.id & 0xFFFF);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
		case MII_ADVERTISE:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
			data->val_out = adapter->phy_regs.advertise;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
		case MII_LPA:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
			data->val_out = adapter->phy_regs.lpa;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
		case MII_EXPANSION:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
			data->val_out = adapter->phy_regs.expansion;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
		case MII_CTRL1000:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
			data->val_out = adapter->phy_regs.ctrl1000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
		case MII_STAT1000:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
			data->val_out = adapter->phy_regs.stat1000;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
		case MII_ESTATUS:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
			data->val_out = adapter->phy_regs.estatus;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
		default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
			return -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
	case SIOCSMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
		return -EOPNOTSUPP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
 * e1000e_hwtstamp_ioctl - control hardware time stamping
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
 * @ifreq: interface request
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
 * Outgoing time stamping can be enabled and disabled. Play nice and
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
 * disable it when requested, although it shouldn't cause any overhead
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
 * when no packet needs it. At most one packet in the queue may be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
 * marked for time stamping, otherwise it would be impossible to tell
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
 * for sure to which packet the hardware time stamp belongs.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
 * Incoming time stamping has to be configured via the hardware filters.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
 * Not all combinations are supported, in particular event type has to be
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
 * specified. Matching the kind of event packet is not supported, with the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
 * exception of "all V2 events regardless of level 2 or 4".
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
static int e1000e_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
	struct hwtstamp_config config;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
	int ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
		return -EFAULT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
	adapter->hwtstamp_config = config;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
	ret_val = e1000e_config_hwtstamp(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
		return ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
	config = adapter->hwtstamp_config;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
	switch (config.rx_filter) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
		/* With V2 type filters which specify a Sync or Delay Request,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
		 * Path Delay Request/Response messages are also time stamped
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
		 * by hardware so notify the caller the requested packets plus
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
		 * some others are time stamped.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5821
		 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5822
		config.rx_filter = HWTSTAMP_FILTER_SOME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5823
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5824
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5825
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5826
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5827
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5828
	return copy_to_user(ifr->ifr_data, &config,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5829
			    sizeof(config)) ? -EFAULT : 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5830
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5831
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5832
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5833
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5834
	switch (cmd) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5835
	case SIOCGMIIPHY:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5836
	case SIOCGMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5837
	case SIOCSMIIREG:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5838
		return e1000_mii_ioctl(netdev, ifr, cmd);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5839
	case SIOCSHWTSTAMP:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5840
		return e1000e_hwtstamp_ioctl(netdev, ifr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5841
	default:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5842
		return -EOPNOTSUPP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5843
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5844
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5845
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5846
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5847
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5848
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5849
	u32 i, mac_reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5850
	u16 phy_reg, wuc_enable;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5851
	int retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5852
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5853
	/* copy MAC RARs to PHY RARs */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5854
	e1000_copy_rx_addrs_to_phy_ich8lan(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5855
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5856
	retval = hw->phy.ops.acquire(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5857
	if (retval) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5858
		e_err("Could not acquire PHY\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5859
		return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5860
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5861
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5862
	/* Enable access to wakeup registers on and set page to BM_WUC_PAGE */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5863
	retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5864
	if (retval)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5865
		goto release;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5866
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5867
	/* copy MAC MTA to PHY MTA - only needed for pchlan */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5868
	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5869
		mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5870
		hw->phy.ops.write_reg_page(hw, BM_MTA(i),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5871
					   (u16)(mac_reg & 0xFFFF));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5872
		hw->phy.ops.write_reg_page(hw, BM_MTA(i) + 1,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5873
					   (u16)((mac_reg >> 16) & 0xFFFF));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5874
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5875
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5876
	/* configure PHY Rx Control register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5877
	hw->phy.ops.read_reg_page(&adapter->hw, BM_RCTL, &phy_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5878
	mac_reg = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5879
	if (mac_reg & E1000_RCTL_UPE)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5880
		phy_reg |= BM_RCTL_UPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5881
	if (mac_reg & E1000_RCTL_MPE)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5882
		phy_reg |= BM_RCTL_MPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5883
	phy_reg &= ~(BM_RCTL_MO_MASK);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5884
	if (mac_reg & E1000_RCTL_MO_3)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5885
		phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5886
			    << BM_RCTL_MO_SHIFT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5887
	if (mac_reg & E1000_RCTL_BAM)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5888
		phy_reg |= BM_RCTL_BAM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5889
	if (mac_reg & E1000_RCTL_PMCF)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5890
		phy_reg |= BM_RCTL_PMCF;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5891
	mac_reg = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5892
	if (mac_reg & E1000_CTRL_RFCE)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5893
		phy_reg |= BM_RCTL_RFCE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5894
	hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5895
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5896
	/* enable PHY wakeup in MAC register */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5897
	ew32(WUFC, wufc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5898
	ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5899
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5900
	/* configure and enable PHY wakeup in PHY registers */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5901
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5902
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5903
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5904
	/* activate PHY wakeup */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5905
	wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5906
	retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5907
	if (retval)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5908
		e_err("Could not set PHY Host Wakeup bit\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5909
release:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5910
	hw->phy.ops.release(hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5911
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5912
	return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5913
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5914
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5915
static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5916
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5917
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5918
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5919
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5920
	u32 ctrl, ctrl_ext, rctl, status;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5921
	/* Runtime suspend should only enable wakeup for link changes */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5922
	u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5923
	int retval = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5924
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5925
	netif_device_detach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5926
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5927
	if (netif_running(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5928
		int count = E1000_CHECK_RESET_COUNT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5929
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5930
		while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5931
			usleep_range(10000, 20000);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5932
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5933
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5934
		e1000e_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5935
		e1000_free_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5936
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5937
	e1000e_reset_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5938
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5939
	status = er32(STATUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5940
	if (status & E1000_STATUS_LU)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5941
		wufc &= ~E1000_WUFC_LNKC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5942
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5943
	if (wufc) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5944
		e1000_setup_rctl(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5945
		e1000e_set_rx_mode(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5946
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5947
		/* turn on all-multi mode if wake on multicast is enabled */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5948
		if (wufc & E1000_WUFC_MC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5949
			rctl = er32(RCTL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5950
			rctl |= E1000_RCTL_MPE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5951
			ew32(RCTL, rctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5952
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5953
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5954
		ctrl = er32(CTRL);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5955
		ctrl |= E1000_CTRL_ADVD3WUC;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5956
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5957
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5958
		ew32(CTRL, ctrl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5959
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5960
		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5961
		    adapter->hw.phy.media_type ==
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5962
		    e1000_media_type_internal_serdes) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5963
			/* keep the laser running in D3 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5964
			ctrl_ext = er32(CTRL_EXT);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5965
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5966
			ew32(CTRL_EXT, ctrl_ext);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5967
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5968
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5969
		if (adapter->flags & FLAG_IS_ICH)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5970
			e1000_suspend_workarounds_ich8lan(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5971
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5972
		/* Allow time for pending master requests to run */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5973
		e1000e_disable_pcie_master(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5974
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5975
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5976
			/* enable wakeup by the PHY */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5977
			retval = e1000_init_phy_wakeup(adapter, wufc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5978
			if (retval)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5979
				return retval;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5980
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5981
			/* enable wakeup by the MAC */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5982
			ew32(WUFC, wufc);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5983
			ew32(WUC, E1000_WUC_PME_EN);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5984
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5985
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5986
		ew32(WUC, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5987
		ew32(WUFC, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5988
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5989
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5990
	if (adapter->hw.phy.type == e1000_phy_igp_3)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5991
		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5992
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5993
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5994
	 * would have already happened in close and is redundant.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5995
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5996
	e1000e_release_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5997
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5998
	/* The pci-e switch on some quad port adapters will report a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5999
	 * correctable error when the MAC transitions from D0 to D3.  To
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6000
	 * prevent this we need to mask off the correctable errors on the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6001
	 * downstream port of the pci-e switch.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6002
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6003
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6004
		struct pci_dev *us_dev = pdev->bus->self;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6005
		u16 devctl;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6006
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6007
		pcie_capability_read_word(us_dev, PCI_EXP_DEVCTL, &devctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6008
		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6009
					   (devctl & ~PCI_EXP_DEVCTL_CERE));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6010
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6011
		pci_save_state(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6012
		pci_prepare_to_sleep(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6013
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6014
		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6015
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6016
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6017
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6018
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6019
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6020
#ifdef CONFIG_PCIEASPM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6021
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6022
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6023
	pci_disable_link_state_locked(pdev, state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6024
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6025
#else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6026
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6027
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6028
	u16 aspm_ctl = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6029
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6030
	if (state & PCIE_LINK_STATE_L0S)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6031
		aspm_ctl |= PCI_EXP_LNKCTL_ASPM_L0S;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6032
	if (state & PCIE_LINK_STATE_L1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6033
		aspm_ctl |= PCI_EXP_LNKCTL_ASPM_L1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6034
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6035
	/* Both device and parent should have the same ASPM setting.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6036
	 * Disable ASPM in downstream component first and then upstream.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6037
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6038
	pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, aspm_ctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6039
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6040
	if (pdev->bus->self)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6041
		pcie_capability_clear_word(pdev->bus->self, PCI_EXP_LNKCTL,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6042
					   aspm_ctl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6043
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6044
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6045
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6046
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6047
	dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6048
		 (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6049
		 (state & PCIE_LINK_STATE_L1) ? "L1" : "");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6050
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6051
	__e1000e_disable_aspm(pdev, state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6052
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6053
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6054
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6055
static bool e1000e_pm_ready(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6056
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6057
	return !!adapter->tx_ring->buffer_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6058
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6059
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6060
static int __e1000_resume(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6061
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6062
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6063
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6064
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6065
	u16 aspm_disable_flag = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6066
	u32 err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6067
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6068
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6069
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6070
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6071
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6072
	if (aspm_disable_flag)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6073
		e1000e_disable_aspm(pdev, aspm_disable_flag);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6074
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6075
	pci_set_master(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6076
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6077
	e1000e_set_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6078
	if (netif_running(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6079
		err = e1000_request_irq(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6080
		if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6081
			return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6082
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6083
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6084
	if (hw->mac.type >= e1000_pch2lan)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6085
		e1000_resume_workarounds_pchlan(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6086
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6087
	e1000e_power_up_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6088
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6089
	/* report the system wakeup cause from S3/S4 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6090
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6091
		u16 phy_data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6092
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6093
		e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6094
		if (phy_data) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6095
			e_info("PHY Wakeup cause - %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6096
			       phy_data & E1000_WUS_EX ? "Unicast Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6097
			       phy_data & E1000_WUS_MC ? "Multicast Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6098
			       phy_data & E1000_WUS_BC ? "Broadcast Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6099
			       phy_data & E1000_WUS_MAG ? "Magic Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6100
			       phy_data & E1000_WUS_LNKC ?
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6101
			       "Link Status Change" : "other");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6102
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6103
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6104
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6105
		u32 wus = er32(WUS);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6106
		if (wus) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6107
			e_info("MAC Wakeup cause - %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6108
			       wus & E1000_WUS_EX ? "Unicast Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6109
			       wus & E1000_WUS_MC ? "Multicast Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6110
			       wus & E1000_WUS_BC ? "Broadcast Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6111
			       wus & E1000_WUS_MAG ? "Magic Packet" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6112
			       wus & E1000_WUS_LNKC ? "Link Status Change" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6113
			       "other");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6114
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6115
		ew32(WUS, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6116
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6117
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6118
	e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6119
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6120
	e1000_init_manageability_pt(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6121
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6122
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6123
		e1000e_up(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6124
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6125
	netif_device_attach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6126
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6127
	/* If the controller has AMT, do not set DRV_LOAD until the interface
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6128
	 * is up.  For all other cases, let the f/w know that the h/w is now
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6129
	 * under the control of the driver.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6130
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6131
	if (!(adapter->flags & FLAG_HAS_AMT))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6132
		e1000e_get_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6133
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6134
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6135
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6136
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6137
#ifdef CONFIG_PM_SLEEP
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6138
static int e1000_suspend(struct device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6139
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6140
	struct pci_dev *pdev = to_pci_dev(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6141
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6142
	return __e1000_shutdown(pdev, false);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6143
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6144
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6145
static int e1000_resume(struct device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6146
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6147
	struct pci_dev *pdev = to_pci_dev(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6148
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6149
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6150
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6151
	if (e1000e_pm_ready(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6152
		adapter->idle_check = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6153
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6154
	return __e1000_resume(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6155
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6156
#endif /* CONFIG_PM_SLEEP */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6157
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6158
#ifdef CONFIG_PM_RUNTIME
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6159
static int e1000_runtime_suspend(struct device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6160
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6161
	struct pci_dev *pdev = to_pci_dev(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6162
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6163
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6164
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6165
	if (!e1000e_pm_ready(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6166
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6167
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6168
	return __e1000_shutdown(pdev, true);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6169
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6170
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6171
static int e1000_idle(struct device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6172
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6173
	struct pci_dev *pdev = to_pci_dev(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6174
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6175
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6176
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6177
	if (!e1000e_pm_ready(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6178
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6179
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6180
	if (adapter->idle_check) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6181
		adapter->idle_check = false;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6182
		if (!e1000e_has_link(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6183
			pm_schedule_suspend(dev, MSEC_PER_SEC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6184
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6185
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6186
	return -EBUSY;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6187
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6188
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6189
static int e1000_runtime_resume(struct device *dev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6190
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6191
	struct pci_dev *pdev = to_pci_dev(dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6192
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6193
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6194
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6195
	if (!e1000e_pm_ready(adapter))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6196
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6197
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6198
	adapter->idle_check = !dev->power.runtime_auto;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6199
	return __e1000_resume(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6200
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6201
#endif /* CONFIG_PM_RUNTIME */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6202
#endif /* CONFIG_PM */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6203
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6204
static void e1000_shutdown(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6205
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6206
	__e1000_shutdown(pdev, false);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6207
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6208
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6209
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6210
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6211
static irqreturn_t e1000_intr_msix(int __always_unused irq, void *data)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6212
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6213
	struct net_device *netdev = data;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6214
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6215
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6216
	if (adapter->msix_entries) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6217
		int vector, msix_irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6218
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6219
		vector = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6220
		msix_irq = adapter->msix_entries[vector].vector;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6221
		disable_irq(msix_irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6222
		e1000_intr_msix_rx(msix_irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6223
		enable_irq(msix_irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6224
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6225
		vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6226
		msix_irq = adapter->msix_entries[vector].vector;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6227
		disable_irq(msix_irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6228
		e1000_intr_msix_tx(msix_irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6229
		enable_irq(msix_irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6230
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6231
		vector++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6232
		msix_irq = adapter->msix_entries[vector].vector;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6233
		disable_irq(msix_irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6234
		e1000_msix_other(msix_irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6235
		enable_irq(msix_irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6236
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6237
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6238
	return IRQ_HANDLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6239
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6240
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6241
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6242
 * e1000_netpoll
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6243
 * @netdev: network interface device structure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6244
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6245
 * Polling 'interrupt' - used by things like netconsole to send skbs
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6246
 * without having to re-enable interrupts. It's not called while
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6247
 * the interrupt routine is executing.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6248
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6249
static void e1000_netpoll(struct net_device *netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6250
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6251
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6252
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6253
	switch (adapter->int_mode) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6254
	case E1000E_INT_MODE_MSIX:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6255
		e1000_intr_msix(adapter->pdev->irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6256
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6257
	case E1000E_INT_MODE_MSI:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6258
		disable_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6259
		e1000_intr_msi(adapter->pdev->irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6260
		enable_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6261
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6262
	default: /* E1000E_INT_MODE_LEGACY */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6263
		disable_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6264
		e1000_intr(adapter->pdev->irq, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6265
		enable_irq(adapter->pdev->irq);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6266
		break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6267
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6268
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6269
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6270
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6271
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6272
 * e1000_io_error_detected - called when PCI error is detected
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6273
 * @pdev: Pointer to PCI device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6274
 * @state: The current pci connection state
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6275
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6276
 * This function is called after a PCI bus error affecting
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6277
 * this device has been detected.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6278
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6279
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6280
						pci_channel_state_t state)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6281
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6282
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6283
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6284
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6285
	netif_device_detach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6286
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6287
	if (state == pci_channel_io_perm_failure)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6288
		return PCI_ERS_RESULT_DISCONNECT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6289
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6290
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6291
		e1000e_down(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6292
	pci_disable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6293
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6294
	/* Request a slot slot reset. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6295
	return PCI_ERS_RESULT_NEED_RESET;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6296
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6297
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6298
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6299
 * e1000_io_slot_reset - called after the pci bus has been reset.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6300
 * @pdev: Pointer to PCI device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6301
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6302
 * Restart the card from scratch, as if from a cold-boot. Implementation
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6303
 * resembles the first-half of the e1000_resume routine.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6304
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6305
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6306
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6307
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6308
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6309
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6310
	u16 aspm_disable_flag = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6311
	int err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6312
	pci_ers_result_t result;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6313
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6314
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6315
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6316
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6317
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6318
	if (aspm_disable_flag)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6319
		e1000e_disable_aspm(pdev, aspm_disable_flag);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6320
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6321
	err = pci_enable_device_mem(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6322
	if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6323
		dev_err(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6324
			"Cannot re-enable PCI device after reset.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6325
		result = PCI_ERS_RESULT_DISCONNECT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6326
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6327
		pdev->state_saved = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6328
		pci_restore_state(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6329
		pci_set_master(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6330
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6331
		pci_enable_wake(pdev, PCI_D3hot, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6332
		pci_enable_wake(pdev, PCI_D3cold, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6333
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6334
		e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6335
		ew32(WUS, ~0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6336
		result = PCI_ERS_RESULT_RECOVERED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6337
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6338
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6339
	pci_cleanup_aer_uncorrect_error_status(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6340
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6341
	return result;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6342
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6343
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6344
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6345
 * e1000_io_resume - called when traffic can start flowing again.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6346
 * @pdev: Pointer to PCI device
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6347
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6348
 * This callback is called when the error recovery driver tells us that
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6349
 * its OK to resume normal operation. Implementation resembles the
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6350
 * second-half of the e1000_resume routine.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6351
 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6352
static void e1000_io_resume(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6353
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6354
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6355
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6356
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6357
	e1000_init_manageability_pt(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6358
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6359
	if (netif_running(netdev)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6360
		if (e1000e_up(adapter)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6361
			dev_err(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6362
				"can't bring device back up after reset\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6363
			return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6364
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6365
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6366
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6367
	netif_device_attach(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6368
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6369
	/* If the controller has AMT, do not set DRV_LOAD until the interface
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6370
	 * is up.  For all other cases, let the f/w know that the h/w is now
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6371
	 * under the control of the driver.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6372
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6373
	if (!(adapter->flags & FLAG_HAS_AMT))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6374
		e1000e_get_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6375
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6376
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6377
static void e1000_print_device_info(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6378
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6379
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6380
	struct net_device *netdev = adapter->netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6381
	u32 ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6382
	u8 pba_str[E1000_PBANUM_LENGTH];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6383
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6384
	/* print bus type/speed/width info */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6385
	e_info("(PCI Express:2.5GT/s:%s) %pM\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6386
	       /* bus width */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6387
	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6388
		"Width x1"),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6389
	       /* MAC address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6390
	       netdev->dev_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6391
	e_info("Intel(R) PRO/%s Network Connection\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6392
	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6393
	ret_val = e1000_read_pba_string_generic(hw, pba_str,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6394
						E1000_PBANUM_LENGTH);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6395
	if (ret_val)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6396
		strlcpy((char *)pba_str, "Unknown", sizeof(pba_str));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6397
	e_info("MAC: %d, PHY: %d, PBA No: %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6398
	       hw->mac.type, hw->phy.type, pba_str);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6399
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6400
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6401
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6402
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6403
	struct e1000_hw *hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6404
	int ret_val;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6405
	u16 buf = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6406
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6407
	if (hw->mac.type != e1000_82573)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6408
		return;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6409
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6410
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6411
	le16_to_cpus(&buf);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6412
	if (!ret_val && (!(buf & (1 << 0)))) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6413
		/* Deep Smart Power Down (DSPD) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6414
		dev_warn(&adapter->pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6415
			 "Warning: detected DSPD enabled in EEPROM\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6416
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6417
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6418
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6419
static int e1000_set_features(struct net_device *netdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6420
			      netdev_features_t features)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6421
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6422
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6423
	netdev_features_t changed = features ^ netdev->features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6424
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6425
	if (changed & (NETIF_F_TSO | NETIF_F_TSO6))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6426
		adapter->flags |= FLAG_TSO_FORCE;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6427
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6428
	if (!(changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6429
			 NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6430
			 NETIF_F_RXALL)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6431
		return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6432
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6433
	if (changed & NETIF_F_RXFCS) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6434
		if (features & NETIF_F_RXFCS) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6435
			adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6436
		} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6437
			/* We need to take it back to defaults, which might mean
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6438
			 * stripping is still disabled at the adapter level.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6439
			 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6440
			if (adapter->flags2 & FLAG2_DFLT_CRC_STRIPPING)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6441
				adapter->flags2 |= FLAG2_CRC_STRIPPING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6442
			else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6443
				adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6444
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6445
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6446
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6447
	netdev->features = features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6448
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6449
	if (netif_running(netdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6450
		e1000e_reinit_locked(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6451
	else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6452
		e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6453
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6454
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6455
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6456
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6457
static const struct net_device_ops e1000e_netdev_ops = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6458
	.ndo_open		= e1000_open,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6459
	.ndo_stop		= e1000_close,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6460
	.ndo_start_xmit		= e1000_xmit_frame,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6461
	.ndo_get_stats64	= e1000e_get_stats64,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6462
	.ndo_set_rx_mode	= e1000e_set_rx_mode,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6463
	.ndo_set_mac_address	= e1000_set_mac,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6464
	.ndo_change_mtu		= e1000_change_mtu,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6465
	.ndo_do_ioctl		= e1000_ioctl,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6466
	.ndo_tx_timeout		= e1000_tx_timeout,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6467
	.ndo_validate_addr	= eth_validate_addr,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6468
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6469
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6470
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6471
#ifdef CONFIG_NET_POLL_CONTROLLER
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6472
	.ndo_poll_controller	= e1000_netpoll,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6473
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6474
	.ndo_set_features = e1000_set_features,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6475
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6476
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6477
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6478
 * e1000_probe - Device Initialization Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6479
 * @pdev: PCI device information struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6480
 * @ent: entry in e1000_pci_tbl
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6481
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6482
 * Returns 0 on success, negative on failure
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6483
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6484
 * e1000_probe initializes an adapter identified by a pci_dev structure.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6485
 * The OS initialization, configuring of the adapter private structure,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6486
 * and a hardware reset occur.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6487
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6488
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6489
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6490
	struct net_device *netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6491
	struct e1000_adapter *adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6492
	struct e1000_hw *hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6493
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6494
	resource_size_t mmio_start, mmio_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6495
	resource_size_t flash_start, flash_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6496
	static int cards_found;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6497
	u16 aspm_disable_flag = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6498
	int bars, i, err, pci_using_dac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6499
	u16 eeprom_data = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6500
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6501
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6502
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6503
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6504
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6505
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6506
	if (aspm_disable_flag)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6507
		e1000e_disable_aspm(pdev, aspm_disable_flag);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6508
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6509
	err = pci_enable_device_mem(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6510
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6511
		return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6512
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6513
	pci_using_dac = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6514
	err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6515
	if (!err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6516
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6517
		if (!err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6518
			pci_using_dac = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6519
	} else {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6520
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6521
		if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6522
			err = dma_set_coherent_mask(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6523
						    DMA_BIT_MASK(32));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6524
			if (err) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6525
				dev_err(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6526
					"No usable DMA configuration, aborting\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6527
				goto err_dma;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6528
			}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6529
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6530
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6531
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6532
	bars = pci_select_bars(pdev, IORESOURCE_MEM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6533
	err = pci_request_selected_regions_exclusive(pdev, bars,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6534
						     e1000e_driver_name);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6535
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6536
		goto err_pci_reg;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6537
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6538
	/* AER (Advanced Error Reporting) hooks */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6539
	pci_enable_pcie_error_reporting(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6540
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6541
	pci_set_master(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6542
	/* PCI config space info */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6543
	err = pci_save_state(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6544
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6545
		goto err_alloc_etherdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6546
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6547
	err = -ENOMEM;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6548
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6549
	if (!netdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6550
		goto err_alloc_etherdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6551
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6552
	SET_NETDEV_DEV(netdev, &pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6553
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6554
	netdev->irq = pdev->irq;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6555
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6556
	pci_set_drvdata(pdev, netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6557
	adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6558
	hw = &adapter->hw;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6559
	adapter->netdev = netdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6560
	adapter->pdev = pdev;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6561
	adapter->ei = ei;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6562
	adapter->pba = ei->pba;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6563
	adapter->flags = ei->flags;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6564
	adapter->flags2 = ei->flags2;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6565
	adapter->hw.adapter = adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6566
	adapter->hw.mac.type = ei->mac;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6567
	adapter->max_hw_frame_size = ei->max_hw_frame_size;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6568
	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6569
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6570
	mmio_start = pci_resource_start(pdev, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6571
	mmio_len = pci_resource_len(pdev, 0);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6572
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6573
	err = -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6574
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6575
	if (!adapter->hw.hw_addr)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6576
		goto err_ioremap;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6577
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6578
	if ((adapter->flags & FLAG_HAS_FLASH) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6579
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6580
		flash_start = pci_resource_start(pdev, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6581
		flash_len = pci_resource_len(pdev, 1);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6582
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6583
		if (!adapter->hw.flash_address)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6584
			goto err_flashmap;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6585
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6586
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6587
	/* Set default EEE advertisement */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6588
	if (adapter->flags2 & FLAG2_HAS_EEE)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6589
		adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6590
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6591
	/* construct the net_device struct */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6592
	netdev->netdev_ops		= &e1000e_netdev_ops;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6593
	e1000e_set_ethtool_ops(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6594
	netdev->watchdog_timeo		= 5 * HZ;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6595
	netif_napi_add(netdev, &adapter->napi, e1000e_poll, 64);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6596
	strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6597
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6598
	netdev->mem_start = mmio_start;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6599
	netdev->mem_end = mmio_start + mmio_len;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6600
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6601
	adapter->bd_number = cards_found++;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6602
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6603
	e1000e_check_options(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6604
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6605
	/* setup adapter struct */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6606
	err = e1000_sw_init(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6607
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6608
		goto err_sw_init;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6609
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6610
	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6611
	memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6612
	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6613
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6614
	err = ei->get_variants(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6615
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6616
		goto err_hw_init;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6617
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6618
	if ((adapter->flags & FLAG_IS_ICH) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6619
	    (adapter->flags & FLAG_READ_ONLY_NVM))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6620
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6621
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6622
	hw->mac.ops.get_bus_info(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6623
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6624
	adapter->hw.phy.autoneg_wait_to_complete = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6625
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6626
	/* Copper options */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6627
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6628
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6629
		adapter->hw.phy.disable_polarity_correction = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6630
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6631
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6632
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6633
	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6634
		dev_info(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6635
			 "PHY reset is blocked due to SOL/IDER session.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6636
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6637
	/* Set initial default active device features */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6638
	netdev->features = (NETIF_F_SG |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6639
			    NETIF_F_HW_VLAN_CTAG_RX |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6640
			    NETIF_F_HW_VLAN_CTAG_TX |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6641
			    NETIF_F_TSO |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6642
			    NETIF_F_TSO6 |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6643
			    NETIF_F_RXHASH |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6644
			    NETIF_F_RXCSUM |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6645
			    NETIF_F_HW_CSUM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6646
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6647
	/* Set user-changeable features (subset of all device features) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6648
	netdev->hw_features = netdev->features;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6649
	netdev->hw_features |= NETIF_F_RXFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6650
	netdev->priv_flags |= IFF_SUPP_NOFCS;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6651
	netdev->hw_features |= NETIF_F_RXALL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6652
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6653
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6654
		netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6655
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6656
	netdev->vlan_features |= (NETIF_F_SG |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6657
				  NETIF_F_TSO |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6658
				  NETIF_F_TSO6 |
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6659
				  NETIF_F_HW_CSUM);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6660
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6661
	netdev->priv_flags |= IFF_UNICAST_FLT;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6662
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6663
	if (pci_using_dac) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6664
		netdev->features |= NETIF_F_HIGHDMA;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6665
		netdev->vlan_features |= NETIF_F_HIGHDMA;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6666
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6667
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6668
	if (e1000e_enable_mng_pass_thru(&adapter->hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6669
		adapter->flags |= FLAG_MNG_PT_ENABLED;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6670
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6671
	/* before reading the NVM, reset the controller to
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6672
	 * put the device in a known good starting state
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6673
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6674
	adapter->hw.mac.ops.reset_hw(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6675
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6676
	/* systems with ASPM and others may see the checksum fail on the first
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6677
	 * attempt. Let's give it a few tries
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6678
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6679
	for (i = 0;; i++) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6680
		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6681
			break;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6682
		if (i == 2) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6683
			dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6684
			err = -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6685
			goto err_eeprom;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6686
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6687
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6688
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6689
	e1000_eeprom_checks(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6690
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6691
	/* copy the MAC address */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6692
	if (e1000e_read_mac_addr(&adapter->hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6693
		dev_err(&pdev->dev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6694
			"NVM Read Error while reading MAC address\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6695
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6696
	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6697
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6698
	if (!is_valid_ether_addr(netdev->dev_addr)) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6699
		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6700
			netdev->dev_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6701
		err = -EIO;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6702
		goto err_eeprom;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6703
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6704
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6705
	init_timer(&adapter->watchdog_timer);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6706
	adapter->watchdog_timer.function = e1000_watchdog;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6707
	adapter->watchdog_timer.data = (unsigned long)adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6708
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6709
	init_timer(&adapter->phy_info_timer);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6710
	adapter->phy_info_timer.function = e1000_update_phy_info;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6711
	adapter->phy_info_timer.data = (unsigned long)adapter;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6712
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6713
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6714
	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6715
	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6716
	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6717
	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6718
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6719
	/* Initialize link parameters. User can change them with ethtool */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6720
	adapter->hw.mac.autoneg = 1;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6721
	adapter->fc_autoneg = true;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6722
	adapter->hw.fc.requested_mode = e1000_fc_default;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6723
	adapter->hw.fc.current_mode = e1000_fc_default;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6724
	adapter->hw.phy.autoneg_advertised = 0x2f;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6725
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6726
	/* ring size defaults */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6727
	adapter->rx_ring->count = E1000_DEFAULT_RXD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6728
	adapter->tx_ring->count = E1000_DEFAULT_TXD;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6729
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6730
	/* Initial Wake on LAN setting - If APM wake is enabled in
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6731
	 * the EEPROM, enable the ACPI Magic Packet filter
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6732
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6733
	if (adapter->flags & FLAG_APME_IN_WUC) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6734
		/* APME bit in EEPROM is mapped to WUC.APME */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6735
		eeprom_data = er32(WUC);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6736
		eeprom_apme_mask = E1000_WUC_APME;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6737
		if ((hw->mac.type > e1000_ich10lan) &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6738
		    (eeprom_data & E1000_WUC_PHY_WAKE))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6739
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6740
	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6741
		if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6742
		    (adapter->hw.bus.func == 1))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6743
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_B,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6744
				       1, &eeprom_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6745
		else
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6746
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_A,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6747
				       1, &eeprom_data);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6748
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6749
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6750
	/* fetch WoL from EEPROM */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6751
	if (eeprom_data & eeprom_apme_mask)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6752
		adapter->eeprom_wol |= E1000_WUFC_MAG;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6753
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6754
	/* now that we have the eeprom settings, apply the special cases
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6755
	 * where the eeprom may be wrong or the board simply won't support
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6756
	 * wake on lan on a particular port
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6757
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6758
	if (!(adapter->flags & FLAG_HAS_WOL))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6759
		adapter->eeprom_wol = 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6760
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6761
	/* initialize the wol settings based on the eeprom settings */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6762
	adapter->wol = adapter->eeprom_wol;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6763
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6764
	/* make sure adapter isn't asleep if manageability is enabled */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6765
	if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) ||
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6766
	    (hw->mac.ops.check_mng_mode(hw)))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6767
		device_wakeup_enable(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6768
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6769
	/* save off EEPROM version number */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6770
	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6771
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6772
	/* reset the hardware with the new settings */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6773
	e1000e_reset(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6774
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6775
	/* If the controller has AMT, do not set DRV_LOAD until the interface
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6776
	 * is up.  For all other cases, let the f/w know that the h/w is now
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6777
	 * under the control of the driver.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6778
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6779
	if (!(adapter->flags & FLAG_HAS_AMT))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6780
		e1000e_get_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6781
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6782
	strlcpy(netdev->name, "eth%d", sizeof(netdev->name));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6783
	err = register_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6784
	if (err)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6785
		goto err_register;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6786
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6787
	/* carrier off reporting is important to ethtool even BEFORE open */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6788
	netif_carrier_off(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6789
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6790
	/* init PTP hardware clock */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6791
	e1000e_ptp_init(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6792
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6793
	e1000_print_device_info(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6794
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6795
	if (pci_dev_run_wake(pdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6796
		pm_runtime_put_noidle(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6797
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6798
	return 0;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6799
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6800
err_register:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6801
	if (!(adapter->flags & FLAG_HAS_AMT))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6802
		e1000e_release_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6803
err_eeprom:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6804
	if (hw->phy.ops.check_reset_block && !hw->phy.ops.check_reset_block(hw))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6805
		e1000_phy_hw_reset(&adapter->hw);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6806
err_hw_init:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6807
	kfree(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6808
	kfree(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6809
err_sw_init:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6810
	if (adapter->hw.flash_address)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6811
		iounmap(adapter->hw.flash_address);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6812
	e1000e_reset_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6813
err_flashmap:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6814
	iounmap(adapter->hw.hw_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6815
err_ioremap:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6816
	free_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6817
err_alloc_etherdev:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6818
	pci_release_selected_regions(pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6819
				     pci_select_bars(pdev, IORESOURCE_MEM));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6820
err_pci_reg:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6821
err_dma:
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6822
	pci_disable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6823
	return err;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6824
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6825
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6826
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6827
 * e1000_remove - Device Removal Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6828
 * @pdev: PCI device information struct
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6829
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6830
 * e1000_remove is called by the PCI subsystem to alert the driver
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6831
 * that it should release a PCI device.  The could be caused by a
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6832
 * Hot-Plug event, or because the driver is going to be removed from
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6833
 * memory.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6834
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6835
static void e1000_remove(struct pci_dev *pdev)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6836
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6837
	struct net_device *netdev = pci_get_drvdata(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6838
	struct e1000_adapter *adapter = netdev_priv(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6839
	bool down = test_bit(__E1000_DOWN, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6840
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6841
	e1000e_ptp_remove(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6842
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6843
	/* The timers may be rescheduled, so explicitly disable them
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6844
	 * from being rescheduled.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6845
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6846
	if (!down)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6847
		set_bit(__E1000_DOWN, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6848
	del_timer_sync(&adapter->watchdog_timer);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6849
	del_timer_sync(&adapter->phy_info_timer);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6850
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6851
	cancel_work_sync(&adapter->reset_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6852
	cancel_work_sync(&adapter->watchdog_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6853
	cancel_work_sync(&adapter->downshift_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6854
	cancel_work_sync(&adapter->update_phy_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6855
	cancel_work_sync(&adapter->print_hang_task);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6856
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6857
	if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6858
		cancel_work_sync(&adapter->tx_hwtstamp_work);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6859
		if (adapter->tx_hwtstamp_skb) {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6860
			dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6861
			adapter->tx_hwtstamp_skb = NULL;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6862
		}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6863
	}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6864
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6865
	if (!(netdev->flags & IFF_UP))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6866
		e1000_power_down_phy(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6867
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6868
	/* Don't lie to e1000_close() down the road. */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6869
	if (!down)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6870
		clear_bit(__E1000_DOWN, &adapter->state);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6871
	unregister_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6872
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6873
	if (pci_dev_run_wake(pdev))
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6874
		pm_runtime_get_noresume(&pdev->dev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6875
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6876
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6877
	 * would have already happened in close and is redundant.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6878
	 */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6879
	e1000e_release_hw_control(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6880
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6881
	e1000e_reset_interrupt_capability(adapter);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6882
	kfree(adapter->tx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6883
	kfree(adapter->rx_ring);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6884
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6885
	iounmap(adapter->hw.hw_addr);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6886
	if (adapter->hw.flash_address)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6887
		iounmap(adapter->hw.flash_address);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6888
	pci_release_selected_regions(pdev,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6889
				     pci_select_bars(pdev, IORESOURCE_MEM));
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6890
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6891
	free_netdev(netdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6892
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6893
	/* AER disable */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6894
	pci_disable_pcie_error_reporting(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6895
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6896
	pci_disable_device(pdev);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6897
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6898
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6899
/* PCI Error Recovery (ERS) */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6900
static const struct pci_error_handlers e1000_err_handler = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6901
	.error_detected = e1000_io_error_detected,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6902
	.slot_reset = e1000_io_slot_reset,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6903
	.resume = e1000_io_resume,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6904
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6905
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6906
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6907
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6908
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6909
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6910
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6911
	  board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6912
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6913
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6914
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6915
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6916
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6917
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6918
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6919
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6920
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6921
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6922
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6923
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6924
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6925
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6926
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6927
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6928
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6929
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6930
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6931
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6932
	  board_80003es2lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6933
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6934
	  board_80003es2lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6935
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6936
	  board_80003es2lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6937
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6938
	  board_80003es2lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6939
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6940
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6941
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6942
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6943
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6944
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6945
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6946
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6947
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6948
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6949
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6950
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6951
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6952
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6953
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6954
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6955
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6956
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6957
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6958
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6959
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6960
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6961
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6962
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6963
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6964
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6965
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_V), board_ich10lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6966
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6967
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6968
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6969
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6970
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6971
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6972
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6973
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6974
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6975
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_LM), board_pch_lpt },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6976
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_V), board_pch_lpt },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6977
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_LM), board_pch_lpt },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6978
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_V), board_pch_lpt },
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6979
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6980
	{ 0, 0, 0, 0, 0, 0, 0 }	/* terminate list */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6981
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6982
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6983
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6984
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6985
static const struct dev_pm_ops e1000_pm_ops = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6986
	SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6987
	SET_RUNTIME_PM_OPS(e1000_runtime_suspend, e1000_runtime_resume,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6988
			   e1000_idle)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6989
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6990
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6991
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6992
/* PCI Device API Driver */
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6993
static struct pci_driver e1000_driver = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6994
	.name     = e1000e_driver_name,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6995
	.id_table = e1000_pci_tbl,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6996
	.probe    = e1000_probe,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6997
	.remove   = e1000_remove,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6998
#ifdef CONFIG_PM
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6999
	.driver   = {
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7000
		.pm = &e1000_pm_ops,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7001
	},
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7002
#endif
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7003
	.shutdown = e1000_shutdown,
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7004
	.err_handler = &e1000_err_handler
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7005
};
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7006
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7007
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7008
 * e1000_init_module - Driver Registration Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7009
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7010
 * e1000_init_module is the first routine called when the driver is
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7011
 * loaded. All it does is register with the PCI subsystem.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7012
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7013
static int __init e1000_init_module(void)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7014
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7015
	int ret;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7016
	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7017
		e1000e_driver_version);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7018
	pr_info("Copyright(c) 1999 - 2013 Intel Corporation.\n");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7019
	ret = pci_register_driver(&e1000_driver);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7020
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7021
	return ret;
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7022
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7023
module_init(e1000_init_module);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7024
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7025
/**
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7026
 * e1000_exit_module - Driver Exit Cleanup Routine
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7027
 *
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7028
 * e1000_exit_module is called just before the driver is removed
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7029
 * from memory.
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7030
 **/
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7031
static void __exit e1000_exit_module(void)
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7032
{
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7033
	pci_unregister_driver(&e1000_driver);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7034
}
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7035
module_exit(e1000_exit_module);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7036
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7037
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7038
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7039
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7040
MODULE_LICENSE("GPL");
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7041
MODULE_VERSION(DRV_VERSION);
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7042
26480934a057 Added all drivers for kernel 3.10.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7043
/* netdev.c */