devices/e1000e/netdev-3.12-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2586 5b89b4e38cdc
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.
2586
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2013 Intel Corporation.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/module.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/types.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/init.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/pci.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/vmalloc.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/pagemap.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/delay.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/netdevice.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <linux/interrupt.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <linux/tcp.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <linux/ipv6.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <linux/slab.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <net/checksum.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <net/ip6_checksum.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <linux/ethtool.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
#include <linux/if_vlan.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include <linux/cpu.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
#include <linux/smp.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#include <linux/pm_qos.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
#include <linux/pm_runtime.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#include <linux/aer.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
#include <linux/prefetch.h>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
#include "e1000.h"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
#define DRV_EXTRAVERSION "-k"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
#define DRV_VERSION "2.3.2" DRV_EXTRAVERSION
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
char e1000e_driver_name[] = "e1000e";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
const char e1000e_driver_version[] = DRV_VERSION;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
static int debug = -1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
module_param(debug, int, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
static const struct e1000_info *e1000_info_tbl[] = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	[board_82571]		= &e1000_82571_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	[board_82572]		= &e1000_82572_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	[board_82573]		= &e1000_82573_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	[board_82574]		= &e1000_82574_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	[board_82583]		= &e1000_82583_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	[board_80003es2lan]	= &e1000_es2_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	[board_ich8lan]		= &e1000_ich8_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	[board_ich9lan]		= &e1000_ich9_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	[board_ich10lan]	= &e1000_ich10_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	[board_pchlan]		= &e1000_pch_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	[board_pch2lan]		= &e1000_pch2_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	[board_pch_lpt]		= &e1000_pch_lpt_info,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
struct e1000_reg_info {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	u32 ofs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	char *name;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
static const struct e1000_reg_info e1000_reg_info_tbl[] = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	/* General Registers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	{E1000_CTRL, "CTRL"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	{E1000_STATUS, "STATUS"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	{E1000_CTRL_EXT, "CTRL_EXT"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	/* Interrupt Registers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	{E1000_ICR, "ICR"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	/* Rx Registers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	{E1000_RCTL, "RCTL"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	{E1000_RDLEN(0), "RDLEN"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	{E1000_RDH(0), "RDH"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	{E1000_RDT(0), "RDT"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	{E1000_RDTR, "RDTR"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	{E1000_RXDCTL(0), "RXDCTL"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	{E1000_ERT, "ERT"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	{E1000_RDBAL(0), "RDBAL"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	{E1000_RDBAH(0), "RDBAH"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	{E1000_RDFH, "RDFH"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	{E1000_RDFT, "RDFT"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	{E1000_RDFHS, "RDFHS"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	{E1000_RDFTS, "RDFTS"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	{E1000_RDFPC, "RDFPC"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	/* Tx Registers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	{E1000_TCTL, "TCTL"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	{E1000_TDBAL(0), "TDBAL"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	{E1000_TDBAH(0), "TDBAH"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	{E1000_TDLEN(0), "TDLEN"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	{E1000_TDH(0), "TDH"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	{E1000_TDT(0), "TDT"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	{E1000_TIDV, "TIDV"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	{E1000_TXDCTL(0), "TXDCTL"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	{E1000_TADV, "TADV"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	{E1000_TARC(0), "TARC"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	{E1000_TDFH, "TDFH"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	{E1000_TDFT, "TDFT"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	{E1000_TDFHS, "TDFHS"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	{E1000_TDFTS, "TDFTS"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	{E1000_TDFPC, "TDFPC"},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	/* List Terminator */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	{0, NULL}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
 * e1000_regdump - register printout routine
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
 * @hw: pointer to the HW structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
 * @reginfo: pointer to the register info table
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	int n = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	char rname[16];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	u32 regs[8];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
	switch (reginfo->ofs) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	case E1000_RXDCTL(0):
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
		for (n = 0; n < 2; n++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
			regs[n] = __er32(hw, E1000_RXDCTL(n));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
	case E1000_TXDCTL(0):
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
		for (n = 0; n < 2; n++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			regs[n] = __er32(hw, E1000_TXDCTL(n));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	case E1000_TARC(0):
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
		for (n = 0; n < 2; n++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
			regs[n] = __er32(hw, E1000_TARC(n));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
		pr_info("%-15s %08x\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
			reginfo->name, __er32(hw, reginfo->ofs));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
	pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
static void e1000e_dump_ps_pages(struct e1000_adapter *adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
				 struct e1000_buffer *bi)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
	struct e1000_ps_page *ps_page;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
	for (i = 0; i < adapter->rx_ps_pages; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
		ps_page = &bi->ps_pages[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
		if (ps_page->page) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
			pr_info("packet dump for ps_page %d:\n", i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
				       16, 1, page_address(ps_page->page),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
				       PAGE_SIZE, true);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
 * e1000e_dump - Print registers, Tx-ring and Rx-ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
static void e1000e_dump(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	struct e1000_reg_info *reginfo;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	struct e1000_ring *tx_ring = adapter->tx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	struct e1000_tx_desc *tx_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	struct my_u0 {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		__le64 a;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
		__le64 b;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	} *u0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	struct e1000_ring *rx_ring = adapter->rx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
	union e1000_rx_desc_packet_split *rx_desc_ps;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	union e1000_rx_desc_extended *rx_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	struct my_u1 {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
		__le64 a;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
		__le64 b;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
		__le64 c;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
		__le64 d;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	} *u1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	u32 staterr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	int i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	if (!netif_msg_hw(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	/* Print netdevice Info */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	if (netdev) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
		dev_info(&adapter->pdev->dev, "Net device Info\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
		pr_info("Device Name     state            trans_start      last_rx\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
		pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
			netdev->state, netdev->trans_start, netdev->last_rx);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	/* Print Registers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	dev_info(&adapter->pdev->dev, "Register Dump\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	pr_info(" Register Name   Value\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	     reginfo->name; reginfo++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
		e1000_regdump(hw, reginfo);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	/* Print Tx Ring Summary */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	if (!netdev || !netif_running(netdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	dev_info(&adapter->pdev->dev, "Tx Ring Summary\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
		0, tx_ring->next_to_use, tx_ring->next_to_clean,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
		(unsigned long long)buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
		buffer_info->length,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
		buffer_info->next_to_watch,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
		(unsigned long long)buffer_info->time_stamp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	/* Print Tx Ring */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	if (!netif_msg_tx_done(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
		goto rx_ring_summary;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	dev_info(&adapter->pdev->dev, "Tx Ring Dump\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	 * Legacy Transmit Descriptor
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	 *   +--------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	 *   +--------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	 *   +--------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	 *   63       48 47        36 35    32 31     24 23    16 15        0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	 *   63      48 47    40 39       32 31             16 15    8 7      0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	 *   +----------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	 *   +----------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	 *   +----------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	 * Extended Data Descriptor (DTYP=0x1)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	 *   +----------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	 * 0 |                     Buffer Address [63:0]                      |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	 *   +----------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	 *   +----------------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	pr_info("Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Legacy format\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Context format\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Data format\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		const char *next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		tx_desc = E1000_TX_DESC(*tx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		u0 = (struct my_u0 *)tx_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
			next_desc = " NTC/U";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		else if (i == tx_ring->next_to_use)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
			next_desc = " NTU";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
		else if (i == tx_ring->next_to_clean)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
			next_desc = " NTC";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
		else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
			next_desc = "";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p%s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
			(!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
			 ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
			i,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
			(unsigned long long)le64_to_cpu(u0->a),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
			(unsigned long long)le64_to_cpu(u0->b),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
			(unsigned long long)buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
			buffer_info->length, buffer_info->next_to_watch,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
			(unsigned long long)buffer_info->time_stamp,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
			buffer_info->skb, next_desc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		if (netif_msg_pktdata(adapter) && buffer_info->skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
				       16, 1, buffer_info->skb->data,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
				       buffer_info->skb->len, true);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	/* Print Rx Ring Summary */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
rx_ring_summary:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	dev_info(&adapter->pdev->dev, "Rx Ring Summary\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	pr_info("Queue [NTU] [NTC]\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	pr_info(" %5d %5X %5X\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
		0, rx_ring->next_to_use, rx_ring->next_to_clean);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	/* Print Rx Ring */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	if (!netif_msg_rx_status(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	dev_info(&adapter->pdev->dev, "Rx Ring Dump\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
	switch (adapter->rx_ps_pages) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
	case 1:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
	case 2:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
	case 3:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		/* [Extended] Packet Split Receive Descriptor Format
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
		 *    +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		 *  0 |                Buffer Address 0 [63:0]              |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		 *    +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		 *  8 |                Buffer Address 1 [63:0]              |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		 *    +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
		 * 16 |                Buffer Address 2 [63:0]              |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		 *    +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		 * 24 |                Buffer Address 3 [63:0]              |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		 *    +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		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");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		/* [Extended] Receive Descriptor (Write-Back) Format
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		 *   63       48 47    32 31     13 12    8 7    4 3        0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		 *   +------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		 * 0 | Packet   | IP     |  Rsvd   | MRQ   | Rsvd | MRQ RSS |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		 *   | Checksum | Ident  |         | Queue |      |  Type   |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		 *   +------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		 *   +------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		 *   63       48 47    32 31            20 19               0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		pr_info("RWB[desc]      [ck ipid mrqhsh] [vl   l0 ee  es] [ l3  l2  l1 hs] [reserved      ] ---------------- [bi->skb] <-- Ext Rx Write-Back format\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
		for (i = 0; i < rx_ring->count; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
			const char *next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
			buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
			rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
			u1 = (struct my_u1 *)rx_desc_ps;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
			staterr =
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
			    le32_to_cpu(rx_desc_ps->wb.middle.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
			if (i == rx_ring->next_to_use)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
				next_desc = " NTU";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
			else if (i == rx_ring->next_to_clean)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
				next_desc = " NTC";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
				next_desc = "";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
			if (staterr & E1000_RXD_STAT_DD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
				/* Descriptor Done */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX ---------------- %p%s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
					"RWB", i,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
					(unsigned long long)le64_to_cpu(u1->a),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
					(unsigned long long)le64_to_cpu(u1->b),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
					(unsigned long long)le64_to_cpu(u1->c),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
					(unsigned long long)le64_to_cpu(u1->d),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
					buffer_info->skb, next_desc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
			} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX %016llX %p%s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
					"R  ", i,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
					(unsigned long long)le64_to_cpu(u1->a),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
					(unsigned long long)le64_to_cpu(u1->b),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
					(unsigned long long)le64_to_cpu(u1->c),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
					(unsigned long long)le64_to_cpu(u1->d),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
					(unsigned long long)buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
					buffer_info->skb, next_desc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
				if (netif_msg_pktdata(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
					e1000e_dump_ps_pages(adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
							     buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	case 0:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		/* Extended Receive Descriptor (Read) Format
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		 *   +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		 * 0 |                Buffer Address [63:0]                |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
		 *   +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
		 * 8 |                      Reserved                       |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
		 *   +-----------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		pr_info("R  [desc]      [buf addr 63:0 ] [reserved 63:0 ] [bi->dma       ] [bi->skb] <-- Ext (Read) format\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
		/* Extended Receive Descriptor (Write-Back) Format
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
		 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
		 *   63       48 47    32 31    24 23            4 3        0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
		 *   +------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		 *   |     RSS Hash      |        |               |         |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		 * 0 +-------------------+  Rsvd  |   Reserved    | MRQ RSS |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
		 *   | Packet   | IP     |        |               |  Type   |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
		 *   | Checksum | Ident  |        |               |         |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
		 *   +------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
		 *   +------------------------------------------------------+
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
		 *   63       48 47    32 31            20 19               0
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
		pr_info("RWB[desc]      [cs ipid    mrq] [vt   ln xe  xs] [bi->skb] <-- Ext (Write-Back) format\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
		for (i = 0; i < rx_ring->count; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
			const char *next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
			buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
			rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
			u1 = (struct my_u1 *)rx_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
			if (i == rx_ring->next_to_use)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
				next_desc = " NTU";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
			else if (i == rx_ring->next_to_clean)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
				next_desc = " NTC";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
				next_desc = "";
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
			if (staterr & E1000_RXD_STAT_DD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
				/* Descriptor Done */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
				pr_info("%s[0x%03X]     %016llX %016llX ---------------- %p%s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
					"RWB", i,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
					(unsigned long long)le64_to_cpu(u1->a),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
					(unsigned long long)le64_to_cpu(u1->b),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
					buffer_info->skb, next_desc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
			} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %p%s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
					"R  ", i,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
					(unsigned long long)le64_to_cpu(u1->a),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
					(unsigned long long)le64_to_cpu(u1->b),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
					(unsigned long long)buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
					buffer_info->skb, next_desc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
				if (netif_msg_pktdata(adapter) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
				    buffer_info->skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
					print_hex_dump(KERN_INFO, "",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
						       DUMP_PREFIX_ADDRESS, 16,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
						       1,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
						       buffer_info->skb->data,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
						       adapter->rx_buffer_len,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
						       true);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
 * e1000_desc_unused - calculate if we have unused descriptors
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
static int e1000_desc_unused(struct e1000_ring *ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	if (ring->next_to_clean > ring->next_to_use)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
		return ring->next_to_clean - ring->next_to_use - 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
 * e1000e_systim_to_hwtstamp - convert system time value to hw time stamp
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
 * @hwtstamps: time stamp structure to update
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
 * @systim: unsigned 64bit system time value.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
 * Convert the system time value stored in the RX/TXSTMP registers into a
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
 * hwtstamp which can be used by the upper level time stamping functions.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
 * The 'systim_lock' spinlock is used to protect the consistency of the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
 * system time value. This is needed because reading the 64 bit time
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
 * value involves reading two 32 bit registers. The first read latches the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
 * value.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
static void e1000e_systim_to_hwtstamp(struct e1000_adapter *adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
				      struct skb_shared_hwtstamps *hwtstamps,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
				      u64 systim)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	u64 ns;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	unsigned long flags;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	spin_lock_irqsave(&adapter->systim_lock, flags);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	ns = timecounter_cyc2time(&adapter->tc, systim);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	spin_unlock_irqrestore(&adapter->systim_lock, flags);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	memset(hwtstamps, 0, sizeof(*hwtstamps));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	hwtstamps->hwtstamp = ns_to_ktime(ns);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
 * e1000e_rx_hwtstamp - utility function which checks for Rx time stamp
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
 * @status: descriptor extended error and status field
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
 * @skb: particular skb to include time stamp
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
 * If the time stamp is valid, convert it into the timecounter ns value
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
 * and store that result into the shhwtstamps structure which is passed
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
 * up the network stack.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
static void e1000e_rx_hwtstamp(struct e1000_adapter *adapter, u32 status,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
			       struct sk_buff *skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	u64 rxstmp;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP) ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	    !(status & E1000_RXDEXT_STATERR_TST) ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	    !(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	/* The Rx time stamp registers contain the time stamp.  No other
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	 * received packet will be time stamped until the Rx time stamp
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	 * registers are read.  Because only one packet can be time stamped
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	 * at a time, the register values must belong to this packet and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
	 * therefore none of the other additional attributes need to be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	 * compared.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	rxstmp = (u64)er32(RXSTMPL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	rxstmp |= (u64)er32(RXSTMPH) << 32;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	e1000e_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), rxstmp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	adapter->flags2 &= ~FLAG2_CHECK_RX_HWTSTAMP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
 * e1000_receive_skb - helper function to handle Rx indications
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 * @staterr: descriptor extended error and status field as written by hardware
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
 * @skb: pointer to sk_buff to be indicated to stack
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
static void e1000_receive_skb(struct e1000_adapter *adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
			      struct net_device *netdev, struct sk_buff *skb,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
			      u32 staterr, __le16 vlan)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	u16 tag = le16_to_cpu(vlan);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	e1000e_rx_hwtstamp(adapter, staterr, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	skb->protocol = eth_type_trans(skb, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	if (staterr & E1000_RXD_STAT_VP)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tag);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	napi_gro_receive(&adapter->napi, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
 * e1000_rx_checksum - Receive Checksum Offload
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
 * @status_err: receive descriptor status and error fields
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
 * @csum: receive descriptor csum field
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
 * @sk_buff: socket buffer with received data
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
			      struct sk_buff *skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	u16 status = (u16)status_err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	u8 errors = (u8)(status_err >> 24);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	skb_checksum_none_assert(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	/* Rx checksum disabled */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	if (!(adapter->netdev->features & NETIF_F_RXCSUM))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	/* Ignore Checksum bit is set */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	if (status & E1000_RXD_STAT_IXSM)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	/* TCP/UDP checksum error bit or IP checksum error bit is set */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		/* let the stack verify checksum errors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		adapter->hw_csum_err++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	/* TCP/UDP Checksum has not been calculated */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	/* It must be a TCP or UDP packet with a valid checksum */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	skb->ip_summed = CHECKSUM_UNNECESSARY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	adapter->hw_csum_good++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	s32 ret_val = __ew32_prepare(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	writel(i, rx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		u32 rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		e_err("ME firmware caused invalid RDT - resetting\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
		schedule_work(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	s32 ret_val = __ew32_prepare(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	writel(i, tx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		u32 tctl = er32(TCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
		ew32(TCTL, tctl & ~E1000_TCTL_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		e_err("ME firmware caused invalid TDT - resetting\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
		schedule_work(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
 * e1000_alloc_rx_buffers - Replace used receive buffers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
				   int cleaned_count, gfp_t gfp)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	union e1000_rx_desc_extended *rx_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	struct sk_buff *skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	unsigned int bufsz = adapter->rx_buffer_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
	i = rx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	while (cleaned_count--) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		skb = buffer_info->skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		if (skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
			skb_trim(skb, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
			goto map_skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
		if (!skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
			/* Better luck next round */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
			adapter->alloc_rx_buff_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
		buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
map_skb:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
						  adapter->rx_buffer_len,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
						  DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
			dev_err(&pdev->dev, "Rx DMA map failed\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
			adapter->rx_dma_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
			/* Force memory writes to complete before letting h/w
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
			 * know there are new descriptors to fetch.  (Only
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
			 * applicable for weak-ordered memory model archs,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
			 * such as IA-64).
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
			wmb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
				e1000e_update_rdt_wa(rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
				writel(i, rx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		if (i == rx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
			i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
		buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	rx_ring->next_to_use = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
				      int cleaned_count, gfp_t gfp)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	union e1000_rx_desc_packet_split *rx_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	struct e1000_ps_page *ps_page;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	struct sk_buff *skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	unsigned int i, j;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	i = rx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
	buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	while (cleaned_count--) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
			ps_page = &buffer_info->ps_pages[j];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
			if (j >= adapter->rx_ps_pages) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
				/* all unused desc entries get hw null ptr */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
				rx_desc->read.buffer_addr[j + 1] =
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
				    ~cpu_to_le64(0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
				continue;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
			if (!ps_page->page) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
				ps_page->page = alloc_page(gfp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
				if (!ps_page->page) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
					adapter->alloc_rx_buff_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
					goto no_buffers;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
				}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
				ps_page->dma = dma_map_page(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
							    ps_page->page,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
							    0, PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
							    DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
				if (dma_mapping_error(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
						      ps_page->dma)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
					dev_err(&adapter->pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
						"Rx DMA page map failed\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
					adapter->rx_dma_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
					goto no_buffers;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
				}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
			/* Refresh the desc even if buffer_addrs
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
			 * didn't change because each write-back
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
			 * erases this info.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
			rx_desc->read.buffer_addr[j + 1] =
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
			    cpu_to_le64(ps_page->dma);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
		skb = __netdev_alloc_skb_ip_align(netdev, adapter->rx_ps_bsize0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
						  gfp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		if (!skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
			adapter->alloc_rx_buff_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
		buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
						  adapter->rx_ps_bsize0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
						  DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
			dev_err(&pdev->dev, "Rx DMA map failed\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
			adapter->rx_dma_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
			/* cleanup skb */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
			dev_kfree_skb_any(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
			buffer_info->skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
			/* Force memory writes to complete before letting h/w
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
			 * know there are new descriptors to fetch.  (Only
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
			 * applicable for weak-ordered memory model archs,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
			 * such as IA-64).
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
			wmb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
				e1000e_update_rdt_wa(rx_ring, i << 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
				writel(i << 1, rx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
		if (i == rx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
			i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
		buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
no_buffers:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
	rx_ring->next_to_use = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
 * @cleaned_count: number of buffers to allocate this pass
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
					 int cleaned_count, gfp_t gfp)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	union e1000_rx_desc_extended *rx_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	struct sk_buff *skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	unsigned int bufsz = 256 - 16;	/* for skb_reserve */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	i = rx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	while (cleaned_count--) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		skb = buffer_info->skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
		if (skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
			skb_trim(skb, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
			goto check_page;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		if (unlikely(!skb)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
			/* Better luck next round */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
			adapter->alloc_rx_buff_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
check_page:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
		/* allocate a new page if necessary */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
		if (!buffer_info->page) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
			buffer_info->page = alloc_page(gfp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
			if (unlikely(!buffer_info->page)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
				adapter->alloc_rx_buff_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		if (!buffer_info->dma) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
			buffer_info->dma = dma_map_page(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
							buffer_info->page, 0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
							PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
							DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
				adapter->alloc_rx_buff_failed++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		if (unlikely(++i == rx_ring->count))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
			i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
		buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	if (likely(rx_ring->next_to_use != i)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
		rx_ring->next_to_use = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
		if (unlikely(i-- == 0))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
			i = (rx_ring->count - 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
		/* Force memory writes to complete before letting h/w
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		 * know there are new descriptors to fetch.  (Only
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		 * applicable for weak-ordered memory model archs,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		 * such as IA-64).
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		wmb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
			e1000e_update_rdt_wa(rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
			writel(i, rx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
				 struct sk_buff *skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	if (netdev->features & NETIF_F_RXHASH)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		skb->rxhash = le32_to_cpu(rss);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
 * e1000_clean_rx_irq - Send received data up the network stack
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
 * the return value indicates whether actual cleaning was done, there
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
 * is no guarantee that everything was cleaned
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
			       int work_to_do)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	struct e1000_buffer *buffer_info, *next_buffer;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	u32 length, staterr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	int cleaned_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	bool cleaned = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	i = rx_ring->next_to_clean;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
	buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	while (staterr & E1000_RXD_STAT_DD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
		struct sk_buff *skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
		if (*work_done >= work_to_do)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
		(*work_done)++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		rmb();	/* read descriptor and rx_buffer_info after status DD */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
		skb = buffer_info->skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
		buffer_info->skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		prefetch(skb->data - NET_IP_ALIGN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
		i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
		if (i == rx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
			i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		prefetch(next_rxd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		next_buffer = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		cleaned = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
		cleaned_count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		dma_unmap_single(&pdev->dev, buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
				 adapter->rx_buffer_len, DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		buffer_info->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		length = le16_to_cpu(rx_desc->wb.upper.length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		/* !EOP means multiple descriptors were used to store a single
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		 * packet, if that's the case we need to toss it.  In fact, we
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		 * need to toss every packet with the EOP bit clear and the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
		 * next frame that _does_ have the EOP bit set, as it is by
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
		 * definition only a frame fragment
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
		if (unlikely(!(staterr & E1000_RXD_STAT_EOP)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
			adapter->flags2 |= FLAG2_IS_DISCARDING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
			/* All receives must fit into a single buffer */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
			e_dbg("Receive packet consumed multiple buffers\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
			/* recycle */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
			buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
			if (staterr & E1000_RXD_STAT_EOP)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
			     !(netdev->features & NETIF_F_RXALL))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
			/* recycle */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
			buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		/* adjust length to remove Ethernet CRC */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
			/* If configured to store CRC, don't subtract FCS,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
			 * but keep the FCS bytes out of the total_rx_bytes
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
			 * counter
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
			if (netdev->features & NETIF_F_RXFCS)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
				total_rx_bytes -= 4;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
				length -= 4;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
		total_rx_bytes += length;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
		total_rx_packets++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
		/* code added for copybreak, this should improve
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
		 * performance for small packets with large amounts
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		 * of reassembly being done in the stack
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
		if (length < copybreak) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
			struct sk_buff *new_skb =
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
			    netdev_alloc_skb_ip_align(netdev, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
			if (new_skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
				skb_copy_to_linear_data_offset(new_skb,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
							       -NET_IP_ALIGN,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
							       (skb->data -
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
								NET_IP_ALIGN),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
							       (length +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
								NET_IP_ALIGN));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
				/* save the skb in buffer_info as good */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
				buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
				skb = new_skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
			/* else just continue with the old one */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
		/* end copybreak code */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		skb_put(skb, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		/* Receive Checksum Offload */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		e1000_rx_checksum(adapter, staterr, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		e1000_receive_skb(adapter, netdev, skb, staterr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
				  rx_desc->wb.upper.vlan);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
next_desc:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		/* return some buffers to hardware, one at a time is too slow */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
					      GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
			cleaned_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		/* use prefetched values */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		rx_desc = next_rxd;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		buffer_info = next_buffer;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	rx_ring->next_to_clean = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
	cleaned_count = e1000_desc_unused(rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	if (cleaned_count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	adapter->total_rx_bytes += total_rx_bytes;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	adapter->total_rx_packets += total_rx_packets;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
	return cleaned;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
static void e1000_put_txbuf(struct e1000_ring *tx_ring,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
			    struct e1000_buffer *buffer_info)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	if (buffer_info->dma) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		if (buffer_info->mapped_as_page)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
				       buffer_info->length, DMA_TO_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
					 buffer_info->length, DMA_TO_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
		buffer_info->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	if (buffer_info->skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		dev_kfree_skb_any(buffer_info->skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		buffer_info->skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	buffer_info->time_stamp = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
static void e1000_print_hw_hang(struct work_struct *work)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	struct e1000_adapter *adapter = container_of(work,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
						     struct e1000_adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
						     print_hang_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	struct e1000_ring *tx_ring = adapter->tx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	unsigned int i = tx_ring->next_to_clean;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	u16 phy_status, phy_1000t_status, phy_ext_status;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	u16 pci_status;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	if (test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	if (!adapter->tx_hang_recheck && (adapter->flags2 & FLAG2_DMA_BURST)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		/* May be block on write-back, flush and detect again
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		 * flush pending descriptor writebacks to memory
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		/* execute the writes immediately */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		/* Due to rare timing issues, write to TIDV again to ensure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		 * the write is successful
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		/* execute the writes immediately */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		adapter->tx_hang_recheck = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	/* Real hang detected */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	adapter->tx_hang_recheck = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	netif_stop_queue(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	e1e_rphy(hw, MII_BMSR, &phy_status);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	e1e_rphy(hw, MII_STAT1000, &phy_1000t_status);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	e1e_rphy(hw, MII_ESTATUS, &phy_ext_status);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	/* detected Hardware unit hang */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	e_err("Detected Hardware Unit Hang:\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	      "  TDH                  <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	      "  TDT                  <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	      "  next_to_use          <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	      "  next_to_clean        <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	      "buffer_info[next_to_clean]:\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	      "  time_stamp           <%lx>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	      "  next_to_watch        <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	      "  jiffies              <%lx>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	      "  next_to_watch.status <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	      "MAC Status             <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
	      "PHY Status             <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	      "PHY 1000BASE-T Status  <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	      "PHY Extended Status    <%x>\n"
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	      "PCI Status             <%x>\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	      readl(tx_ring->head), readl(tx_ring->tail), tx_ring->next_to_use,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	      tx_ring->next_to_clean, tx_ring->buffer_info[eop].time_stamp,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	      eop, jiffies, eop_desc->upper.fields.status, er32(STATUS),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
	      phy_status, phy_1000t_status, phy_ext_status, pci_status);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
	/* Suggest workaround for known h/w issue */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	if ((hw->mac.type == e1000_pchlan) && (er32(CTRL) & E1000_CTRL_TFCE))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		e_err("Try turning off Tx pause (flow control) via ethtool\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
 * e1000e_tx_hwtstamp_work - check for Tx time stamp
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
 * @work: pointer to work struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
 * This work function polls the TSYNCTXCTL valid bit to determine when a
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
 * timestamp has been taken for the current stored skb.  The timestamp must
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
 * be for this skb because only one such packet is allowed in the queue.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
static void e1000e_tx_hwtstamp_work(struct work_struct *work)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	struct e1000_adapter *adapter = container_of(work, struct e1000_adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
						     tx_hwtstamp_work);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	if (!adapter->tx_hwtstamp_skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		struct skb_shared_hwtstamps shhwtstamps;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		u64 txstmp;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		txstmp = er32(TXSTMPL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		txstmp |= (u64)er32(TXSTMPH) << 32;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		e1000e_systim_to_hwtstamp(adapter, &shhwtstamps, txstmp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		adapter->tx_hwtstamp_skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		/* reschedule to check later */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		schedule_work(&adapter->tx_hwtstamp_work);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
 * @tx_ring: Tx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
 * the return value indicates whether actual cleaning was done, there
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
 * is no guarantee that everything was cleaned
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	struct e1000_tx_desc *tx_desc, *eop_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	unsigned int i, eop;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	unsigned int count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	unsigned int bytes_compl = 0, pkts_compl = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	i = tx_ring->next_to_clean;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	eop = tx_ring->buffer_info[i].next_to_watch;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	       (count < tx_ring->count)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		bool cleaned = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		rmb();		/* read buffer_info after eop_desc */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		for (; !cleaned; count++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
			tx_desc = E1000_TX_DESC(*tx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
			buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
			cleaned = (i == eop);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
			if (cleaned) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
				total_tx_packets += buffer_info->segs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
				total_tx_bytes += buffer_info->bytecount;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
				if (buffer_info->skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
					bytes_compl += buffer_info->skb->len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
					pkts_compl++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
				}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
			e1000_put_txbuf(tx_ring, buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
			tx_desc->upper.data = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
			i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
			if (i == tx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
				i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		if (i == tx_ring->next_to_use)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		eop = tx_ring->buffer_info[i].next_to_watch;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	tx_ring->next_to_clean = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
#define TX_WAKE_THRESHOLD 32
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	if (count && netif_carrier_ok(netdev) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		/* Make sure that anybody stopping the queue after this
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		 * sees the new next_to_clean.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		smp_mb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		if (netif_queue_stopped(netdev) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
			netif_wake_queue(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
			++adapter->restart_queue;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	if (adapter->detect_tx_hung) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
		/* Detect a transmit hang in hardware, this serializes the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
		 * check with the clearing of time_stamp and movement of i
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		adapter->detect_tx_hung = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		if (tx_ring->buffer_info[i].time_stamp &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
			       + (adapter->tx_timeout_factor * HZ)) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
		    !(er32(STATUS) & E1000_STATUS_TXOFF))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
			schedule_work(&adapter->print_hang_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
			adapter->tx_hang_recheck = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	adapter->total_tx_bytes += total_tx_bytes;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	adapter->total_tx_packets += total_tx_packets;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	return count < tx_ring->count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
 * the return value indicates whether actual cleaning was done, there
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
 * is no guarantee that everything was cleaned
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
				  int work_to_do)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	struct e1000_buffer *buffer_info, *next_buffer;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	struct e1000_ps_page *ps_page;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	struct sk_buff *skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	unsigned int i, j;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	u32 length, staterr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	int cleaned_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	bool cleaned = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	i = rx_ring->next_to_clean;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
	while (staterr & E1000_RXD_STAT_DD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		if (*work_done >= work_to_do)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
		(*work_done)++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		skb = buffer_info->skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
		rmb();	/* read descriptor and rx_buffer_info after status DD */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		/* in the packet split case this is header only */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		prefetch(skb->data - NET_IP_ALIGN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		if (i == rx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
			i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
		prefetch(next_rxd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		next_buffer = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
		cleaned = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
		cleaned_count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
		dma_unmap_single(&pdev->dev, buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
				 adapter->rx_ps_bsize0, DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		buffer_info->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
		/* see !EOP comment in other Rx routine */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
		if (!(staterr & E1000_RXD_STAT_EOP))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
			adapter->flags2 |= FLAG2_IS_DISCARDING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
			e_dbg("Packet Split buffers didn't pick up the full packet\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
			dev_kfree_skb_irq(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
			if (staterr & E1000_RXD_STAT_EOP)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
			     !(netdev->features & NETIF_F_RXALL))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
			dev_kfree_skb_irq(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		length = le16_to_cpu(rx_desc->wb.middle.length0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
		if (!length) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
			e_dbg("Last part of the packet spanning multiple descriptors\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
			dev_kfree_skb_irq(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		/* Good Receive */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		skb_put(skb, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
		{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
			/* this looks ugly, but it seems compiler issues make
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
			 * it more efficient than reusing j
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
			int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
			/* page alloc/put takes too long and effects small
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
			 * packet throughput, so unsplit small packets and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
			 * save the alloc/put only valid in softirq (napi)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
			 * context to call kmap_*
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
			if (l1 && (l1 <= copybreak) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
			    ((length + l1) <= adapter->rx_ps_bsize0)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
				u8 *vaddr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
				ps_page = &buffer_info->ps_pages[0];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
				/* there is no documentation about how to call
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
				 * kmap_atomic, so we can't hold the mapping
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
				 * very long
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
				 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
				dma_sync_single_for_cpu(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
							ps_page->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
							PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
							DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
				vaddr = kmap_atomic(ps_page->page);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
				memcpy(skb_tail_pointer(skb), vaddr, l1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
				kunmap_atomic(vaddr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
				dma_sync_single_for_device(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
							   ps_page->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
							   PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
							   DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
				/* remove the CRC */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
				if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
					if (!(netdev->features & NETIF_F_RXFCS))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
						l1 -= 4;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
				}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
				skb_put(skb, l1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
				goto copydone;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
			}	/* if */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
			if (!length)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			ps_page = &buffer_info->ps_pages[j];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
				       DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
			ps_page->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
			skb_fill_page_desc(skb, j, ps_page->page, 0, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
			ps_page->page = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
			skb->len += length;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
			skb->data_len += length;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
			skb->truesize += PAGE_SIZE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
		/* strip the ethernet crc, problem is we're using pages now so
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
		 * this whole operation can get a little cpu intensive
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
			if (!(netdev->features & NETIF_F_RXFCS))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
				pskb_trim(skb, skb->len - 4);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
copydone:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		total_rx_bytes += skb->len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
		total_rx_packets++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		e1000_rx_checksum(adapter, staterr, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		if (rx_desc->wb.upper.header_status &
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		    cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
			adapter->rx_hdr_split++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		e1000_receive_skb(adapter, netdev, skb, staterr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
				  rx_desc->wb.middle.vlan);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
next_desc:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
		buffer_info->skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		/* return some buffers to hardware, one at a time is too slow */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
					      GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
			cleaned_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
		/* use prefetched values */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		rx_desc = next_rxd;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		buffer_info = next_buffer;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	rx_ring->next_to_clean = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	cleaned_count = e1000_desc_unused(rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	if (cleaned_count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	adapter->total_rx_bytes += total_rx_bytes;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
	adapter->total_rx_packets += total_rx_packets;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	return cleaned;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
 * e1000_consume_page - helper function
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
			       u16 length)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	bi->page = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
	skb->len += length;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	skb->data_len += length;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
	skb->truesize += PAGE_SIZE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
 * the return value indicates whether actual cleaning was done, there
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
 * is no guarantee that everything was cleaned
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
				     int work_to_do)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	struct e1000_buffer *buffer_info, *next_buffer;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	u32 length, staterr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	int cleaned_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	bool cleaned = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	struct skb_shared_info *shinfo;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	i = rx_ring->next_to_clean;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	while (staterr & E1000_RXD_STAT_DD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
		struct sk_buff *skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
		if (*work_done >= work_to_do)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
		(*work_done)++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
		rmb();	/* read descriptor and rx_buffer_info after status DD */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
		skb = buffer_info->skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
		buffer_info->skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		++i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		if (i == rx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
			i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
		prefetch(next_rxd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		next_buffer = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		cleaned = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
		cleaned_count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		dma_unmap_page(&pdev->dev, buffer_info->dma, PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
			       DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		buffer_info->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		length = le16_to_cpu(rx_desc->wb.upper.length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		/* errors is only valid for DD + EOP descriptors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		if (unlikely((staterr & E1000_RXD_STAT_EOP) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
			     ((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
			      !(netdev->features & NETIF_F_RXALL)))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
			/* recycle both page and skb */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
			buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
			/* an error means any chain goes out the window too */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
			if (rx_ring->rx_skb_top)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
				dev_kfree_skb_irq(rx_ring->rx_skb_top);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
			rx_ring->rx_skb_top = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
#define rxtop (rx_ring->rx_skb_top)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		if (!(staterr & E1000_RXD_STAT_EOP)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
			/* this descriptor is only the beginning (or middle) */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
			if (!rxtop) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
				/* this is the beginning of a chain */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
				rxtop = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
						   0, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
			} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
				/* this is the middle of a chain */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
				shinfo = skb_shinfo(rxtop);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
				skb_fill_page_desc(rxtop, shinfo->nr_frags,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
						   buffer_info->page, 0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
						   length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
				/* re-use the skb, only consumed the page */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
				buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
			e1000_consume_page(buffer_info, rxtop, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
			if (rxtop) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
				/* end of the chain */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
				shinfo = skb_shinfo(rxtop);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
				skb_fill_page_desc(rxtop, shinfo->nr_frags,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
						   buffer_info->page, 0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
						   length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
				/* re-use the current skb, we only consumed the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
				 * page
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
				 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
				buffer_info->skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
				skb = rxtop;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
				rxtop = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
				e1000_consume_page(buffer_info, skb, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
			} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
				/* no chain, got EOP, this buf is the packet
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
				 * copybreak to save the put_page/alloc_page
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
				 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
				if (length <= copybreak &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
				    skb_tailroom(skb) >= length) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
					u8 *vaddr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
					vaddr = kmap_atomic(buffer_info->page);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
					memcpy(skb_tail_pointer(skb), vaddr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
					       length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
					kunmap_atomic(vaddr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
					/* re-use the page, so don't erase
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
					 * buffer_info->page
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
					 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
					skb_put(skb, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
				} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
					skb_fill_page_desc(skb, 0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
							   buffer_info->page, 0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
							   length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
					e1000_consume_page(buffer_info, skb,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
							   length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
				}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		/* Receive Checksum Offload */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
		e1000_rx_checksum(adapter, staterr, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		/* probably a little skewed due to removing CRC */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		total_rx_bytes += skb->len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		total_rx_packets++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		/* eth type trans needs skb->data to point to something */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		if (!pskb_may_pull(skb, ETH_HLEN)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
			e_err("pskb_may_pull failed.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
			dev_kfree_skb_irq(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
			goto next_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		e1000_receive_skb(adapter, netdev, skb, staterr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
				  rx_desc->wb.upper.vlan);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
next_desc:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		/* return some buffers to hardware, one at a time is too slow */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
					      GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			cleaned_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		/* use prefetched values */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		rx_desc = next_rxd;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		buffer_info = next_buffer;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	rx_ring->next_to_clean = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	cleaned_count = e1000_desc_unused(rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	if (cleaned_count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	adapter->total_rx_bytes += total_rx_bytes;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
	adapter->total_rx_packets += total_rx_packets;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
	return cleaned;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	struct e1000_ps_page *ps_page;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	unsigned int i, j;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
	/* Free all the Rx ring sk_buffs */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	for (i = 0; i < rx_ring->count; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		if (buffer_info->dma) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
			if (adapter->clean_rx == e1000_clean_rx_irq)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
				dma_unmap_single(&pdev->dev, buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
						 adapter->rx_buffer_len,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
						 DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
				dma_unmap_page(&pdev->dev, buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
					       PAGE_SIZE, DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
				dma_unmap_single(&pdev->dev, buffer_info->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
						 adapter->rx_ps_bsize0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
						 DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
			buffer_info->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		if (buffer_info->page) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
			put_page(buffer_info->page);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
			buffer_info->page = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		if (buffer_info->skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
			dev_kfree_skb(buffer_info->skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
			buffer_info->skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
			ps_page = &buffer_info->ps_pages[j];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
			if (!ps_page->page)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
				       DMA_FROM_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
			ps_page->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
			put_page(ps_page->page);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
			ps_page->page = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	/* there also may be some cached data from a chained receive */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
	if (rx_ring->rx_skb_top) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		dev_kfree_skb(rx_ring->rx_skb_top);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		rx_ring->rx_skb_top = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	/* Zero out the descriptor ring */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	memset(rx_ring->desc, 0, rx_ring->size);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
	rx_ring->next_to_clean = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	rx_ring->next_to_use = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	writel(0, rx_ring->head);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	if (rx_ring->adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		e1000e_update_rdt_wa(rx_ring, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
		writel(0, rx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
static void e1000e_downshift_workaround(struct work_struct *work)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	struct e1000_adapter *adapter = container_of(work,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
						     struct e1000_adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
						     downshift_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	if (test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
 * e1000_intr_msi - Interrupt Handler
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
 * @irq: interrupt number
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
 * @data: pointer to a network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
static irqreturn_t e1000_intr_msi(int __always_unused irq, void *data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	struct net_device *netdev = data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	u32 icr = er32(ICR);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	/* read ICR disables interrupts using IAM */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	if (icr & E1000_ICR_LSC) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		hw->mac.get_link_status = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		/* ICH8 workaround-- Call gig speed drop workaround on cable
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
		 * disconnect (LSC) before accessing any PHY registers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		    (!(er32(STATUS) & E1000_STATUS_LU)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
			schedule_work(&adapter->downshift_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		/* 80003ES2LAN workaround-- For packet buffer work-around on
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		 * link down event; disable receives here in the ISR and reset
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
		 * adapter in watchdog
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		if (netif_carrier_ok(netdev) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
			/* disable receives */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
			u32 rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
			adapter->flags |= FLAG_RESTART_NOW;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
		/* guard against interrupt when we're going down */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	/* Reset on uncorrectable ECC error */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
		u32 pbeccsts = er32(PBECCSTS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
		adapter->corr_errors +=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		adapter->uncorr_errors +=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
		/* Do the reset outside of interrupt context */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		schedule_work(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		/* return immediately since reset is imminent */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	if (napi_schedule_prep(&adapter->napi)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		adapter->total_tx_bytes = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
		adapter->total_tx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		adapter->total_rx_bytes = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		adapter->total_rx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		__napi_schedule(&adapter->napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
 * e1000_intr - Interrupt Handler
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
 * @irq: interrupt number
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
 * @data: pointer to a network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
static irqreturn_t e1000_intr(int __always_unused irq, void *data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	struct net_device *netdev = data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	u32 rctl, icr = er32(ICR);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
		return IRQ_NONE;	/* Not our interrupt */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	 * not set, then the adapter didn't send an interrupt
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	if (!(icr & E1000_ICR_INT_ASSERTED))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		return IRQ_NONE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	/* Interrupt Auto-Mask...upon reading ICR,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	 * interrupts are masked.  No need for the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	 * IMC write
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	if (icr & E1000_ICR_LSC) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		hw->mac.get_link_status = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		/* ICH8 workaround-- Call gig speed drop workaround on cable
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		 * disconnect (LSC) before accessing any PHY registers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		    (!(er32(STATUS) & E1000_STATUS_LU)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
			schedule_work(&adapter->downshift_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
		/* 80003ES2LAN workaround--
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		 * For packet buffer work-around on link down event;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		 * disable receives here in the ISR and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		 * reset adapter in watchdog
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		if (netif_carrier_ok(netdev) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
			/* disable receives */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
			rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
			adapter->flags |= FLAG_RESTART_NOW;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		/* guard against interrupt when we're going down */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
	/* Reset on uncorrectable ECC error */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		u32 pbeccsts = er32(PBECCSTS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
		adapter->corr_errors +=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
		adapter->uncorr_errors +=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
		/* Do the reset outside of interrupt context */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		schedule_work(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		/* return immediately since reset is imminent */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	if (napi_schedule_prep(&adapter->napi)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		adapter->total_tx_bytes = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		adapter->total_tx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		adapter->total_rx_bytes = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
		adapter->total_rx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		__napi_schedule(&adapter->napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
	return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	struct net_device *netdev = data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	u32 icr = er32(ICR);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
		if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
			ew32(IMS, E1000_IMS_OTHER);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		return IRQ_NONE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	if (icr & adapter->eiac_mask)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		ew32(ICS, (icr & adapter->eiac_mask));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	if (icr & E1000_ICR_OTHER) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		if (!(icr & E1000_ICR_LSC))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
			goto no_link_interrupt;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
		hw->mac.get_link_status = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		/* guard against interrupt when we're going down */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
no_link_interrupt:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
	if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
static irqreturn_t e1000_intr_msix_tx(int __always_unused irq, void *data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
	struct net_device *netdev = data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	struct e1000_ring *tx_ring = adapter->tx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
	adapter->total_tx_bytes = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	adapter->total_tx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	if (!e1000_clean_tx_irq(tx_ring))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		/* Ring was not completely cleaned, so fire another interrupt */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
		ew32(ICS, tx_ring->ims_val);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
static irqreturn_t e1000_intr_msix_rx(int __always_unused irq, void *data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	struct net_device *netdev = data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	struct e1000_ring *rx_ring = adapter->rx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	/* Write the ITR value calculated at the end of the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	 * previous interrupt.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	if (rx_ring->set_itr) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
		writel(1000000000 / (rx_ring->itr_val * 256),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
		       rx_ring->itr_register);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
		rx_ring->set_itr = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	if (napi_schedule_prep(&adapter->napi)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
		adapter->total_rx_bytes = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
		adapter->total_rx_packets = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
		__napi_schedule(&adapter->napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
 * e1000_configure_msix - Configure MSI-X hardware
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
 * e1000_configure_msix sets up the hardware to properly
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
 * generate MSI-X interrupts.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
static void e1000_configure_msix(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	struct e1000_ring *rx_ring = adapter->rx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
	struct e1000_ring *tx_ring = adapter->tx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	int vector = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	u32 ctrl_ext, ivar = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	adapter->eiac_mask = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	if (hw->mac.type == e1000_82574) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		u32 rfctl = er32(RFCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
		rfctl |= E1000_RFCTL_ACK_DIS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
		ew32(RFCTL, rfctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	/* Configure Rx vector */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	rx_ring->ims_val = E1000_IMS_RXQ0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	adapter->eiac_mask |= rx_ring->ims_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
	if (rx_ring->itr_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
		writel(1000000000 / (rx_ring->itr_val * 256),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		       rx_ring->itr_register);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
		writel(1, rx_ring->itr_register);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	/* Configure Tx vector */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
	tx_ring->ims_val = E1000_IMS_TXQ0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
	vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	if (tx_ring->itr_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		writel(1000000000 / (tx_ring->itr_val * 256),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		       tx_ring->itr_register);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
		writel(1, tx_ring->itr_register);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	adapter->eiac_mask |= tx_ring->ims_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	/* set vector for Other Causes, e.g. link changes */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	if (rx_ring->itr_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		writel(1000000000 / (rx_ring->itr_val * 256),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
		       hw->hw_addr + E1000_EITR_82574(vector));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	/* Cause Tx interrupts on every write back */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	ivar |= (1 << 31);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	ew32(IVAR, ivar);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	/* enable MSI-X PBA support */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	ctrl_ext = er32(CTRL_EXT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	/* Auto-Mask Other interrupts upon ICR read */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	ew32(CTRL_EXT, ctrl_ext);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
	if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		pci_disable_msix(adapter->pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		kfree(adapter->msix_entries);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		adapter->msix_entries = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		pci_disable_msi(adapter->pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
		adapter->flags &= ~FLAG_MSI_ENABLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
 * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
 * Attempt to configure interrupts using the best available
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
 * capabilities of the hardware and kernel.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	int err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	switch (adapter->int_mode) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	case E1000E_INT_MODE_MSIX:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
		if (adapter->flags & FLAG_HAS_MSIX) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
			adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
			adapter->msix_entries = kcalloc(adapter->num_vectors,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
							sizeof(struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
							       msix_entry),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
							GFP_KERNEL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
			if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
				for (i = 0; i < adapter->num_vectors; i++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
					adapter->msix_entries[i].entry = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
				err = pci_enable_msix(adapter->pdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
						      adapter->msix_entries,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
						      adapter->num_vectors);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
				if (err == 0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
					return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
			/* MSI-X failed, so fall through and try MSI */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			e_err("Failed to initialize MSI-X interrupts.  Falling back to MSI interrupts.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
			e1000e_reset_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
		adapter->int_mode = E1000E_INT_MODE_MSI;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		/* Fall through */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	case E1000E_INT_MODE_MSI:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		if (!pci_enable_msi(adapter->pdev)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
			adapter->flags |= FLAG_MSI_ENABLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
			e_err("Failed to initialize MSI interrupts.  Falling back to legacy interrupts.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
		/* Fall through */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
	case E1000E_INT_MODE_LEGACY:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		/* Don't do anything; this is the system default */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	/* store the number of vectors being used */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	adapter->num_vectors = 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
 * e1000_request_msix - Initialize MSI-X interrupts
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
 * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
 * kernel.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
static int e1000_request_msix(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	int err = 0, vector = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
		snprintf(adapter->rx_ring->name,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
			 sizeof(adapter->rx_ring->name) - 1,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
			 "%s-rx-0", netdev->name);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
	err = request_irq(adapter->msix_entries[vector].vector,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
			  netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
		return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	adapter->rx_ring->itr_register = adapter->hw.hw_addr +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	    E1000_EITR_82574(vector);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	adapter->rx_ring->itr_val = adapter->itr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		snprintf(adapter->tx_ring->name,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
			 sizeof(adapter->tx_ring->name) - 1,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
			 "%s-tx-0", netdev->name);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	err = request_irq(adapter->msix_entries[vector].vector,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
			  netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	adapter->tx_ring->itr_register = adapter->hw.hw_addr +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	    E1000_EITR_82574(vector);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	adapter->tx_ring->itr_val = adapter->itr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
	vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	err = request_irq(adapter->msix_entries[vector].vector,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
			  e1000_msix_other, 0, netdev->name, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
		return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	e1000_configure_msix(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
 * e1000_request_irq - initialize interrupts
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
 * Attempts to configure interrupts using the best available
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
 * capabilities of the hardware and kernel.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
static int e1000_request_irq(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	int err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
		err = e1000_request_msix(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
		if (!err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
			return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
		/* fall back to MSI */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
		e1000e_reset_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		adapter->int_mode = E1000E_INT_MODE_MSI;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
		e1000e_set_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
	if (adapter->flags & FLAG_MSI_ENABLED) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
		err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
				  netdev->name, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
		if (!err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
			return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
		/* fall back to legacy interrupt */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
		e1000e_reset_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
			  netdev->name, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
		e_err("Unable to allocate interrupt, Error: %d\n", err);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
static void e1000_free_irq(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
	if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
		int vector = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		free_irq(adapter->msix_entries[vector].vector, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
		vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
		free_irq(adapter->msix_entries[vector].vector, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
		vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		/* Other Causes interrupt vector */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
		free_irq(adapter->msix_entries[vector].vector, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	free_irq(adapter->pdev->irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
 * e1000_irq_disable - Mask off interrupt generation on the NIC
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
static void e1000_irq_disable(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	ew32(IMC, ~0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	if (adapter->msix_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
		ew32(EIAC_82574, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
		int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
		for (i = 0; i < adapter->num_vectors; i++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
			synchronize_irq(adapter->msix_entries[i].vector);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
		synchronize_irq(adapter->pdev->irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
 * e1000_irq_enable - Enable default interrupt generation settings
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
static void e1000_irq_enable(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	} else if (hw->mac.type == e1000_pch_lpt) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
		ew32(IMS, IMS_ENABLE_MASK);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
 * e1000e_get_hw_control - get control of the h/w from f/w
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
 * @adapter: address of board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
 * e1000e_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
 * For ASF and Pass Through versions of f/w this means that
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
 * the driver is loaded. For AMT version (only with 82573)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
 * of the f/w this means that the network i/f is open.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
void e1000e_get_hw_control(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	u32 ctrl_ext;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	u32 swsm;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	/* Let firmware know the driver has taken over */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		swsm = er32(SWSM);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
		ctrl_ext = er32(CTRL_EXT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
 * e1000e_release_hw_control - release control of the h/w to f/w
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
 * @adapter: address of board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
 * e1000e_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
 * For ASF and Pass Through versions of f/w this means that the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
 * driver is no longer loaded. For AMT version (only with 82573) i
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
 * of the f/w this means that the network i/f is closed.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
void e1000e_release_hw_control(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	u32 ctrl_ext;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	u32 swsm;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	/* Let firmware taken over control of h/w */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		swsm = er32(SWSM);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		ctrl_ext = er32(CTRL_EXT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
 * e1000_alloc_ring_dma - allocate memory for a ring structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
				struct e1000_ring *ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
					GFP_KERNEL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	if (!ring->desc)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
		return -ENOMEM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
 * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
 * @tx_ring: Tx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
 * Return 0 on success, negative on failure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
int e1000e_setup_tx_resources(struct e1000_ring *tx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
	int err = -ENOMEM, size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	size = sizeof(struct e1000_buffer) * tx_ring->count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	tx_ring->buffer_info = vzalloc(size);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	if (!tx_ring->buffer_info)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
		goto err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	/* round up to nearest 4K */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	tx_ring->size = ALIGN(tx_ring->size, 4096);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	err = e1000_alloc_ring_dma(adapter, tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		goto err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	tx_ring->next_to_use = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	tx_ring->next_to_clean = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
err:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	vfree(tx_ring->buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
 * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
 * Returns 0 on success, negative on failure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
int e1000e_setup_rx_resources(struct e1000_ring *rx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	int i, size, desc_len, err = -ENOMEM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	size = sizeof(struct e1000_buffer) * rx_ring->count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	rx_ring->buffer_info = vzalloc(size);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	if (!rx_ring->buffer_info)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		goto err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	for (i = 0; i < rx_ring->count; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
						sizeof(struct e1000_ps_page),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
						GFP_KERNEL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		if (!buffer_info->ps_pages)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
			goto err_pages;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	desc_len = sizeof(union e1000_rx_desc_packet_split);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	/* Round up to nearest 4K */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
	rx_ring->size = rx_ring->count * desc_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	rx_ring->size = ALIGN(rx_ring->size, 4096);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
	err = e1000_alloc_ring_dma(adapter, rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
		goto err_pages;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	rx_ring->next_to_clean = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	rx_ring->next_to_use = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	rx_ring->rx_skb_top = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
err_pages:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
	for (i = 0; i < rx_ring->count; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
		buffer_info = &rx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
		kfree(buffer_info->ps_pages);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
err:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
	vfree(rx_ring->buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	e_err("Unable to allocate memory for the receive descriptor ring\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
	return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
 * e1000_clean_tx_ring - Free Tx Buffers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
 * @tx_ring: Tx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	unsigned long size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	for (i = 0; i < tx_ring->count; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
		e1000_put_txbuf(tx_ring, buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	netdev_reset_queue(adapter->netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
	size = sizeof(struct e1000_buffer) * tx_ring->count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	memset(tx_ring->buffer_info, 0, size);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	memset(tx_ring->desc, 0, tx_ring->size);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	tx_ring->next_to_use = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	tx_ring->next_to_clean = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
	writel(0, tx_ring->head);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	if (tx_ring->adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
		e1000e_update_tdt_wa(tx_ring, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
		writel(0, tx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
 * e1000e_free_tx_resources - Free Tx Resources per Queue
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
 * @tx_ring: Tx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
 * Free all transmit software resources
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
void e1000e_free_tx_resources(struct e1000_ring *tx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	e1000_clean_tx_ring(tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	vfree(tx_ring->buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	tx_ring->buffer_info = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
			  tx_ring->dma);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	tx_ring->desc = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
 * e1000e_free_rx_resources - Free Rx Resources
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
 * @rx_ring: Rx descriptor ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
 * Free all receive software resources
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
void e1000e_free_rx_resources(struct e1000_ring *rx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
	struct e1000_adapter *adapter = rx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	e1000_clean_rx_ring(rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	for (i = 0; i < rx_ring->count; i++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
		kfree(rx_ring->buffer_info[i].ps_pages);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	vfree(rx_ring->buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	rx_ring->buffer_info = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
			  rx_ring->dma);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	rx_ring->desc = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
 * e1000_update_itr - update the dynamic ITR value based on statistics
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
 * @adapter: pointer to adapter
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
 * @itr_setting: current adapter->itr
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
 * @packets: the number of packets during this measurement interval
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
 * @bytes: the number of bytes during this measurement interval
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
 *      Stores a new ITR value based on packets and byte
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
 *      counts during the last interrupt.  The advantage of per interrupt
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
 *      computation is faster updates and more accurate ITR for the current
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
 *      traffic pattern.  Constants in this function were computed
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
 *      based on theoretical maximum wire speed and thresholds were set based
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
 *      on testing data as well as attempting to minimize response time
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
 *      while increasing bulk throughput.  This functionality is controlled
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
 *      by the InterruptThrottleRate module parameter.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
static unsigned int e1000_update_itr(u16 itr_setting, int packets, int bytes)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	unsigned int retval = itr_setting;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	if (packets == 0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
		return itr_setting;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	switch (itr_setting) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	case lowest_latency:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
		/* handle TSO and jumbo frames */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
		if (bytes / packets > 8000)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
			retval = bulk_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		else if ((packets < 5) && (bytes > 512))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
			retval = low_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	case low_latency:	/* 50 usec aka 20000 ints/s */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
		if (bytes > 10000) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
			/* this if handles the TSO accounting */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
			if (bytes / packets > 8000)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
				retval = bulk_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
			else if ((packets < 10) || ((bytes / packets) > 1200))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
				retval = bulk_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
			else if ((packets > 35))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
				retval = lowest_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
		} else if (bytes / packets > 2000) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
			retval = bulk_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		} else if (packets <= 2 && bytes < 512) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
			retval = lowest_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	case bulk_latency:	/* 250 usec aka 4000 ints/s */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		if (bytes > 25000) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
			if (packets > 35)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
				retval = low_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
		} else if (bytes < 6000) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
			retval = low_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	return retval;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
static void e1000_set_itr(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	u16 current_itr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	u32 new_itr = adapter->itr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
	if (adapter->link_speed != SPEED_1000) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		current_itr = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		new_itr = 4000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
		goto set_itr_now;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	if (adapter->flags2 & FLAG2_DISABLE_AIM) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
		new_itr = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		goto set_itr_now;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
	adapter->tx_itr = e1000_update_itr(adapter->tx_itr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
					   adapter->total_tx_packets,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
					   adapter->total_tx_bytes);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		adapter->tx_itr = low_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	adapter->rx_itr = e1000_update_itr(adapter->rx_itr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
					   adapter->total_rx_packets,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
					   adapter->total_rx_bytes);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
		adapter->rx_itr = low_latency;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	/* counts and packets in update_itr are dependent on these numbers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
	switch (current_itr) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	case lowest_latency:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
		new_itr = 70000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	case low_latency:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
		new_itr = 20000;	/* aka hwitr = ~200 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	case bulk_latency:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
		new_itr = 4000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
set_itr_now:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
	if (new_itr != adapter->itr) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		/* this attempts to bias the interrupt rate towards Bulk
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
		 * by adding intermediate steps when interrupt rate is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		 * increasing
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
		new_itr = new_itr > adapter->itr ?
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
		    min(adapter->itr + (new_itr >> 2), new_itr) : new_itr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		adapter->itr = new_itr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		adapter->rx_ring->itr_val = new_itr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		if (adapter->msix_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
			adapter->rx_ring->set_itr = 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
		else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
			e1000e_write_itr(adapter, new_itr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
 * e1000e_write_itr - write the ITR value to the appropriate registers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
 * @adapter: address of board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
 * @itr: new ITR value to program
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
 * e1000e_write_itr determines if the adapter is in MSI-X mode
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
 * and, if so, writes the EITR registers with the ITR value.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
 * Otherwise, it writes the ITR value into the ITR register.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
	u32 new_itr = itr ? 1000000000 / (itr * 256) : 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
	if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		int vector;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		for (vector = 0; vector < adapter->num_vectors; vector++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
			writel(new_itr, hw->hw_addr + E1000_EITR_82574(vector));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		ew32(ITR, new_itr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
 * e1000_alloc_queues - Allocate memory for all rings
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
 * @adapter: board private structure to initialize
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
static int e1000_alloc_queues(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
	int size = sizeof(struct e1000_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
	adapter->tx_ring = kzalloc(size, GFP_KERNEL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
	if (!adapter->tx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
		goto err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	adapter->tx_ring->count = adapter->tx_ring_count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	adapter->tx_ring->adapter = adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	adapter->rx_ring = kzalloc(size, GFP_KERNEL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
	if (!adapter->rx_ring)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
		goto err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	adapter->rx_ring->count = adapter->rx_ring_count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
	adapter->rx_ring->adapter = adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
err:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
	e_err("Unable to allocate memory for queues\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	kfree(adapter->rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	kfree(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	return -ENOMEM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
 * e1000e_poll - NAPI Rx polling callback
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
 * @napi: struct associated with this polling callback
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
 * @weight: number of packets driver is allowed to process this poll
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
static int e1000e_poll(struct napi_struct *napi, int weight)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
						     napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	struct net_device *poll_dev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	int tx_cleaned = 1, work_done = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	adapter = netdev_priv(poll_dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
	if (!adapter->msix_entries ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	    (adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
	adapter->clean_rx(adapter->rx_ring, &work_done, weight);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	if (!tx_cleaned)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
		work_done = weight;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	/* If weight not fully consumed, exit the polling mode */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	if (work_done < weight) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
		if (adapter->itr_setting & 3)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
			e1000_set_itr(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
		napi_complete(napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
			if (adapter->msix_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
				ew32(IMS, adapter->rx_ring->ims_val);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
				e1000_irq_enable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	return work_done;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
static int e1000_vlan_rx_add_vid(struct net_device *netdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
				 __always_unused __be16 proto, u16 vid)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	u32 vfta, index;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	/* don't update vlan cookie if already programmed */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
	if ((adapter->hw.mng_cookie.status &
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	    (vid == adapter->mng_vlan_id))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	/* add VID to filter table */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
		index = (vid >> 5) & 0x7F;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
		vfta |= (1 << (vid & 0x1F));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		hw->mac.ops.write_vfta(hw, index, vfta);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	set_bit(vid, adapter->active_vlans);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
				  __always_unused __be16 proto, u16 vid)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	u32 vfta, index;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	if ((adapter->hw.mng_cookie.status &
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
	    (vid == adapter->mng_vlan_id)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
		/* release control to f/w */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		e1000e_release_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
	/* remove VID from filter table */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
		index = (vid >> 5) & 0x7F;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		vfta &= ~(1 << (vid & 0x1F));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
		hw->mac.ops.write_vfta(hw, index, vfta);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	clear_bit(vid, adapter->active_vlans);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
 * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
 * @adapter: board private structure to initialize
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	u32 rctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
		/* disable VLAN receive filtering */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
		rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
		rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		ew32(RCTL, rctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
			e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
					       adapter->mng_vlan_id);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
 * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
 * @adapter: board private structure to initialize
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	u32 rctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
		/* enable VLAN receive filtering */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		rctl |= E1000_RCTL_VFE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
		rctl &= ~E1000_RCTL_CFIEN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		ew32(RCTL, rctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
 * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
 * @adapter: board private structure to initialize
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
	u32 ctrl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	/* disable VLAN tag insert/strip */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
	ctrl = er32(CTRL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	ctrl &= ~E1000_CTRL_VME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	ew32(CTRL, ctrl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
 * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
 * @adapter: board private structure to initialize
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	u32 ctrl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	/* enable VLAN tag insert/strip */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
	ctrl = er32(CTRL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
	ctrl |= E1000_CTRL_VME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
	ew32(CTRL, ctrl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	u16 vid = adapter->hw.mng_cookie.vlan_id;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	u16 old_vid = adapter->mng_vlan_id;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		e1000_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		adapter->mng_vlan_id = vid;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q), old_vid);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
static void e1000_restore_vlan(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	u16 vid;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	    e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
	u32 manc, manc2h, mdef, i, j;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	manc = er32(MANC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	/* enable receiving management packets to the host. this will probably
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
	 * generate destination unreachable messages from the host OS, but
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	 * the packets will be handled on SMBUS
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	manc |= E1000_MANC_EN_MNG2HOST;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	manc2h = er32(MANC2H);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
	switch (hw->mac.type) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		manc2h |= (E1000_MANC2H_PORT_623 | E1000_MANC2H_PORT_664);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	case e1000_82574:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	case e1000_82583:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		/* Check if IPMI pass-through decision filter already exists;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		 * if so, enable it.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		for (i = 0, j = 0; i < 8; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
			mdef = er32(MDEF(i));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
			/* Ignore filters with anything other than IPMI ports */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
			if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
				continue;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
			/* Enable this decision filter in MANC2H */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
			if (mdef)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
				manc2h |= (1 << i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
			j |= mdef;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
		if (j == (E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
		/* Create new decision filter in an empty filter */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
		for (i = 0, j = 0; i < 8; i++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
			if (er32(MDEF(i)) == 0) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
				ew32(MDEF(i), (E1000_MDEF_PORT_623 |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
					       E1000_MDEF_PORT_664));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
				manc2h |= (1 << 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
				j++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
		if (!j)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
			e_warn("Unable to create IPMI pass-through filter\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	ew32(MANC2H, manc2h);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	ew32(MANC, manc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
 * e1000_configure_tx - Configure Transmit Unit after Reset
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
 * Configure the Tx unit of the MAC after a reset.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
static void e1000_configure_tx(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	struct e1000_ring *tx_ring = adapter->tx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	u64 tdba;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	u32 tdlen, tarc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	/* Setup the HW Tx Head and Tail descriptor pointers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	tdba = tx_ring->dma;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	ew32(TDBAL(0), (tdba & DMA_BIT_MASK(32)));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	ew32(TDBAH(0), (tdba >> 32));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	ew32(TDLEN(0), tdlen);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	ew32(TDH(0), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	ew32(TDT(0), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	tx_ring->head = adapter->hw.hw_addr + E1000_TDH(0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	tx_ring->tail = adapter->hw.hw_addr + E1000_TDT(0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
	/* Set the Tx Interrupt Delay register */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	ew32(TIDV, adapter->tx_int_delay);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	/* Tx irq moderation */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	ew32(TADV, adapter->tx_abs_int_delay);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	if (adapter->flags2 & FLAG2_DMA_BURST) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
		u32 txdctl = er32(TXDCTL(0));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
		txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
			    E1000_TXDCTL_WTHRESH);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		/* set up some performance related parameters to encourage the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		 * hardware to use the bus more efficiently in bursts, depends
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		 * on the tx_int_delay to be enabled,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		 * wthresh = 1 ==> burst write is disabled to avoid Tx stalls
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		 * hthresh = 1 ==> prefetch when one or more available
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
		 * pthresh = 0x1f ==> prefetch if internal cache 31 or less
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		 * BEWARE: this seems to work but should be considered first if
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		 * there are Tx hangs or other Tx related bugs
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
		ew32(TXDCTL(0), txdctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	/* erratum work around: set txdctl the same for both queues */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	ew32(TXDCTL(1), er32(TXDCTL(0)));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
		tarc = er32(TARC(0));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		/* set the speed mode bit, we'll clear it if we're not at
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		 * gigabit link later
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
#define SPEED_MODE_BIT (1 << 21)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		tarc |= SPEED_MODE_BIT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
		ew32(TARC(0), tarc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	/* errata: program both queues to unweighted RR */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
		tarc = er32(TARC(0));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		tarc |= 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
		ew32(TARC(0), tarc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
		tarc = er32(TARC(1));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
		tarc |= 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		ew32(TARC(1), tarc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	/* Setup Transmit Descriptor Settings for eop descriptor */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	/* only set IDE if we are delaying interrupts using the timers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	if (adapter->tx_int_delay)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	/* enable Report Status bit */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
	hw->mac.ops.config_collision_dist(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
 * e1000_setup_rctl - configure the receive control registers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
 * @adapter: Board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
static void e1000_setup_rctl(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	u32 rctl, rfctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	u32 pages = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	/* Workaround Si errata on PCHx - configure jumbo frame flow.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
	 * If jumbo frames not set, program related MAC/PHY registers
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
	 * to h/w defaults
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
	if (hw->mac.type >= e1000_pch2lan) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
		s32 ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		if (adapter->netdev->mtu > ETH_DATA_LEN)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
		if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
			e_dbg("failed to enable|disable jumbo frame workaround mode\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	/* Program MC offset vector base */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	    E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
	    (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	/* Do not Store bad packets */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	rctl &= ~E1000_RCTL_SBP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	/* Enable Long Packet receive */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
		rctl &= ~E1000_RCTL_LPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
		rctl |= E1000_RCTL_LPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	/* Some systems expect that the CRC is included in SMBUS traffic. The
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	 * hardware strips the CRC before sending to both SMBUS (BMC) and to
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	 * host memory when this is enabled
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
		rctl |= E1000_RCTL_SECRC;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		u16 phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
		phy_data &= 0xfff8;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
		phy_data |= (1 << 2);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
		e1e_wphy(hw, PHY_REG(770, 26), phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
		e1e_rphy(hw, 22, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
		phy_data &= 0x0fff;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
		phy_data |= (1 << 14);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		e1e_wphy(hw, 0x10, 0x2823);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
		e1e_wphy(hw, 0x11, 0x0003);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
		e1e_wphy(hw, 22, phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	/* Setup buffer sizes */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	rctl &= ~E1000_RCTL_SZ_4096;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	rctl |= E1000_RCTL_BSEX;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	switch (adapter->rx_buffer_len) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	case 2048:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		rctl |= E1000_RCTL_SZ_2048;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		rctl &= ~E1000_RCTL_BSEX;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
	case 4096:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		rctl |= E1000_RCTL_SZ_4096;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	case 8192:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		rctl |= E1000_RCTL_SZ_8192;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
	case 16384:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		rctl |= E1000_RCTL_SZ_16384;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	/* Enable Extended Status in all Receive Descriptors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	rfctl = er32(RFCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	rfctl |= E1000_RFCTL_EXTEN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	ew32(RFCTL, rfctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	/* 82571 and greater support packet-split where the protocol
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
	 * header is placed in skb->data and the packet data is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	 * In the case of a non-split, skb->data is linearly filled,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	 * followed by the page buffers.  Therefore, skb->data is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
	 * sized to hold the largest protocol header.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	 * allocations using alloc_page take too long for regular MTU
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	 * so only enable packet split for jumbo frames
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	 * Using pages when the page size is greater than 16k wastes
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	 * a lot of memory, since we allocate 3 pages at all times
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
	 * per packet.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		adapter->rx_ps_pages = pages;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
		adapter->rx_ps_pages = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	if (adapter->rx_ps_pages) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		u32 psrctl = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		/* Enable Packet split descriptors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		rctl |= E1000_RCTL_DTYP_PS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
		psrctl |= adapter->rx_ps_bsize0 >> E1000_PSRCTL_BSIZE0_SHIFT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
		switch (adapter->rx_ps_pages) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
		case 3:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
			psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE3_SHIFT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
			/* fall-through */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
		case 2:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
			psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE2_SHIFT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
			/* fall-through */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		case 1:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
			psrctl |= PAGE_SIZE >> E1000_PSRCTL_BSIZE1_SHIFT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
		ew32(PSRCTL, psrctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	/* This is useful for sniffing bad packets. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
	if (adapter->netdev->features & NETIF_F_RXALL) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
		/* UPE and MPE will be handled by normal PROMISC logic
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
		 * in e1000e_set_rx_mode
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		rctl |= (E1000_RCTL_SBP |	/* Receive bad packets */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
			 E1000_RCTL_BAM |	/* RX All Bcast Pkts */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
			 E1000_RCTL_PMCF);	/* RX All MAC Ctrl Pkts */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
		rctl &= ~(E1000_RCTL_VFE |	/* Disable VLAN filter */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
			  E1000_RCTL_DPF |	/* Allow filtered pause */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
			  E1000_RCTL_CFIEN);	/* Dis VLAN CFIEN Filter */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		 * and that breaks VLANs.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	ew32(RCTL, rctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	/* just started the receive unit, no need to restart */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	adapter->flags &= ~FLAG_RESTART_NOW;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
 * e1000_configure_rx - Configure Receive Unit after Reset
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
 * Configure the Rx unit of the MAC after a reset.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
static void e1000_configure_rx(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	struct e1000_ring *rx_ring = adapter->rx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	u64 rdba;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	u32 rdlen, rctl, rxcsum, ctrl_ext;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	if (adapter->rx_ps_pages) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
		/* this is a 32 byte descriptor */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
		rdlen = rx_ring->count *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
		    sizeof(union e1000_rx_desc_packet_split);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		adapter->clean_rx = e1000_clean_rx_irq_ps;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		adapter->clean_rx = e1000_clean_rx_irq;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	/* disable receives while setting up the descriptors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
	usleep_range(10000, 20000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	if (adapter->flags2 & FLAG2_DMA_BURST) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		/* set the writeback threshold (only takes effect if the RDTR
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		 * is set). set GRAN=1 and write back up to 0x4 worth, and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
		 * enable prefetching of 0x20 Rx descriptors
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
		 * granularity = 01
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
		 * wthresh = 04,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		 * hthresh = 04,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
		 * pthresh = 0x20
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
		ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
		/* override the delay timers for enabling bursting, only if
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
		 * the value was not set by the user via module options
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
		if (adapter->rx_int_delay == DEFAULT_RDTR)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
			adapter->rx_int_delay = BURST_RDTR;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
		if (adapter->rx_abs_int_delay == DEFAULT_RADV)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
			adapter->rx_abs_int_delay = BURST_RADV;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	/* set the Receive Delay Timer Register */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	ew32(RDTR, adapter->rx_int_delay);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	/* irq moderation */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	ew32(RADV, adapter->rx_abs_int_delay);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	if ((adapter->itr_setting != 0) && (adapter->itr != 0))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
		e1000e_write_itr(adapter, adapter->itr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	ctrl_ext = er32(CTRL_EXT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	/* Auto-Mask interrupts upon ICR access */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
	ctrl_ext |= E1000_CTRL_EXT_IAME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	ew32(IAM, 0xffffffff);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	ew32(CTRL_EXT, ctrl_ext);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	 * the Base and Length of the Rx Descriptor Ring
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	rdba = rx_ring->dma;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	ew32(RDBAL(0), (rdba & DMA_BIT_MASK(32)));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	ew32(RDBAH(0), (rdba >> 32));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	ew32(RDLEN(0), rdlen);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	ew32(RDH(0), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	ew32(RDT(0), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	rx_ring->head = adapter->hw.hw_addr + E1000_RDH(0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	rx_ring->tail = adapter->hw.hw_addr + E1000_RDT(0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	/* Enable Receive Checksum Offload for TCP and UDP */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	rxcsum = er32(RXCSUM);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	if (adapter->netdev->features & NETIF_F_RXCSUM)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
		rxcsum |= E1000_RXCSUM_TUOFL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
		rxcsum &= ~E1000_RXCSUM_TUOFL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	ew32(RXCSUM, rxcsum);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	/* With jumbo frames, excessive C-state transition latencies result
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	 * in dropped transactions.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		u32 lat =
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		    ((er32(PBA) & E1000_PBA_RXA_MASK) * 1024 -
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		     adapter->max_frame_size) * 8 / 1000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		if (adapter->flags & FLAG_IS_ICH) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
			u32 rxdctl = er32(RXDCTL(0));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
			ew32(RXDCTL(0), rxdctl | 0x3);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		pm_qos_update_request(&adapter->netdev->pm_qos_req, lat);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
		pm_qos_update_request(&adapter->netdev->pm_qos_req,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
				      PM_QOS_DEFAULT_VALUE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	/* Enable Receives */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	ew32(RCTL, rctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
 * e1000e_write_mc_addr_list - write multicast addresses to MTA
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
 * Writes multicast address list to the MTA hash table.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
 * Returns: -ENOMEM on failure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
 *                0 on no addresses written
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
 *                X on writing X addresses to MTA
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
static int e1000e_write_mc_addr_list(struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	struct netdev_hw_addr *ha;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	u8 *mta_list;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	if (netdev_mc_empty(netdev)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
		/* nothing to program, so clear mc list */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
		hw->mac.ops.update_mc_addr_list(hw, NULL, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	mta_list = kzalloc(netdev_mc_count(netdev) * ETH_ALEN, GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
	if (!mta_list)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
		return -ENOMEM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	/* update_mc_addr_list expects a packed array of only addresses. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	netdev_for_each_mc_addr(ha, netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	    memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	hw->mac.ops.update_mc_addr_list(hw, mta_list, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	kfree(mta_list);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	return netdev_mc_count(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
 * e1000e_write_uc_addr_list - write unicast addresses to RAR table
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
 * Writes unicast address list to the RAR table.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
 * Returns: -ENOMEM on failure/insufficient address space
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
 *                0 on no addresses written
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
 *                X on writing X addresses to the RAR table
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
static int e1000e_write_uc_addr_list(struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	unsigned int rar_entries = hw->mac.rar_entry_count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	int count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	/* save a rar entry for our hardware address */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	rar_entries--;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	/* save a rar entry for the LAA workaround */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
		rar_entries--;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	/* return ENOMEM indicating insufficient memory for addresses */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	if (netdev_uc_count(netdev) > rar_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		return -ENOMEM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	if (!netdev_uc_empty(netdev) && rar_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
		struct netdev_hw_addr *ha;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
		/* write the addresses in reverse order to avoid write
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
		 * combining
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		netdev_for_each_uc_addr(ha, netdev) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
			if (!rar_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
			hw->mac.ops.rar_set(hw, ha->addr, rar_entries--);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
			count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	/* zero out the remaining RAR entries not used above */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	for (; rar_entries > 0; rar_entries--) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
		ew32(RAH(rar_entries), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
		ew32(RAL(rar_entries), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	return count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
 * e1000e_set_rx_mode - secondary unicast, Multicast and Promiscuous mode set
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
 * The ndo_set_rx_mode entry point is called whenever the unicast or multicast
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
 * address list or the network interface flags are updated.  This routine is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
 * responsible for configuring the hardware for proper unicast, multicast,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
 * promiscuous mode, and all-multi behavior.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
static void e1000e_set_rx_mode(struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	u32 rctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	/* Check for Promiscuous and All Multicast modes */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	/* clear the affected bits */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	if (netdev->flags & IFF_PROMISC) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
		/* Do not hardware filter VLANs in promisc mode */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
		e1000e_vlan_filter_disable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
		int count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
		if (netdev->flags & IFF_ALLMULTI) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
			rctl |= E1000_RCTL_MPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
			/* Write addresses to the MTA, if the attempt fails
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
			 * then we should just turn on promiscuous mode so
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
			 * that we can at least receive multicast traffic
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
			count = e1000e_write_mc_addr_list(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
			if (count < 0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
				rctl |= E1000_RCTL_MPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
		e1000e_vlan_filter_enable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		/* Write addresses to available RAR registers, if there is not
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
		 * sufficient space to store all the addresses then enable
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
		 * unicast promiscuous mode
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
		count = e1000e_write_uc_addr_list(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
		if (count < 0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
			rctl |= E1000_RCTL_UPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	ew32(RCTL, rctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
		e1000e_vlan_strip_enable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
		e1000e_vlan_strip_disable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
static void e1000e_setup_rss_hash(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	u32 mrqc, rxcsum;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	static const u32 rsskey[10] = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
		0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
		0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	/* Fill out hash function seed */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	for (i = 0; i < 10; i++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
		ew32(RSSRK(i), rsskey[i]);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	/* Direct all traffic to queue 0 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	for (i = 0; i < 32; i++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		ew32(RETA(i), 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
	/* Disable raw packet checksumming so that RSS hash is placed in
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	 * descriptor on writeback.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	rxcsum = er32(RXCSUM);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	rxcsum |= E1000_RXCSUM_PCSD;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	ew32(RXCSUM, rxcsum);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	mrqc = (E1000_MRQC_RSS_FIELD_IPV4 |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
		E1000_MRQC_RSS_FIELD_IPV4_TCP |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		E1000_MRQC_RSS_FIELD_IPV6 |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		E1000_MRQC_RSS_FIELD_IPV6_TCP |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
		E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	ew32(MRQC, mrqc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
 * e1000e_get_base_timinca - get default SYSTIM time increment attributes
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
 * @timinca: pointer to returned time increment attributes
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
 * Get attributes for incrementing the System Time Register SYSTIML/H at
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
 * the default base frequency, and set the cyclecounter shift value.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	u32 incvalue, incperiod, shift;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	/* Make sure clock is enabled on I217 before checking the frequency */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	if ((hw->mac.type == e1000_pch_lpt) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	    !(er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_ENABLED) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	    !(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_ENABLED)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
		u32 fextnvm7 = er32(FEXTNVM7);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
		if (!(fextnvm7 & (1 << 0))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
			ew32(FEXTNVM7, fextnvm7 | (1 << 0));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
			e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	switch (hw->mac.type) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	case e1000_pch2lan:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	case e1000_pch_lpt:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
		/* On I217, the clock frequency is 25MHz or 96MHz as
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		 * indicated by the System Clock Frequency Indication
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		if ((hw->mac.type != e1000_pch_lpt) ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
		    (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
			/* Stable 96MHz frequency */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
			incperiod = INCPERIOD_96MHz;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
			incvalue = INCVALUE_96MHz;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
			shift = INCVALUE_SHIFT_96MHz;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
			adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHz;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
		/* fall-through */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	case e1000_82574:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	case e1000_82583:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		/* Stable 25MHz frequency */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		incperiod = INCPERIOD_25MHz;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		incvalue = INCVALUE_25MHz;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
		shift = INCVALUE_SHIFT_25MHz;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		adapter->cc.shift = shift;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		return -EINVAL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	*timinca = ((incperiod << E1000_TIMINCA_INCPERIOD_SHIFT) |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
		    ((incvalue << shift) & E1000_TIMINCA_INCVALUE_MASK));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
 * e1000e_config_hwtstamp - configure the hwtstamp registers and enable/disable
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
 * Outgoing time stamping can be enabled and disabled. Play nice and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
 * disable it when requested, although it shouldn't cause any overhead
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
 * when no packet needs it. At most one packet in the queue may be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
 * marked for time stamping, otherwise it would be impossible to tell
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
 * for sure to which packet the hardware time stamp belongs.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
 * Incoming time stamping has to be configured via the hardware filters.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
 * Not all combinations are supported, in particular event type has to be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
 * specified. Matching the kind of event packet is not supported, with the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
 * exception of "all V2 events regardless of level 2 or 4".
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
static int e1000e_config_hwtstamp(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	struct hwtstamp_config *config = &adapter->hwtstamp_config;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	u32 rxmtrl = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	u16 rxudp = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	bool is_l4 = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	bool is_l2 = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	u32 regval;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	s32 ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
		return -EINVAL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	/* flags reserved for future extensions - must be zero */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	if (config->flags)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		return -EINVAL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	switch (config->tx_type) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	case HWTSTAMP_TX_OFF:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
		tsync_tx_ctl = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	case HWTSTAMP_TX_ON:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
		return -ERANGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	switch (config->rx_filter) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	case HWTSTAMP_FILTER_NONE:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
		tsync_rx_ctl = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
		rxmtrl = E1000_RXMTRL_PTP_V1_SYNC_MESSAGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
		is_l4 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
		rxmtrl = E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		is_l4 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
		/* Also time stamps V2 L2 Path Delay Request/Response */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
		rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
		is_l2 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		/* Also time stamps V2 L2 Path Delay Request/Response. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
		rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
		is_l2 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
		/* Hardware cannot filter just V2 L4 Sync messages;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
		 * fall-through to V2 (both L2 and L4) Sync.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		/* Also time stamps V2 Path Delay Request/Response. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		is_l2 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		is_l4 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		/* Hardware cannot filter just V2 L4 Delay Request messages;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
		 * fall-through to V2 (both L2 and L4) Delay Request.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
		/* Also time stamps V2 Path Delay Request/Response. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		is_l2 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
		is_l4 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		/* Hardware cannot filter just V2 L4 or L2 Event messages;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		 * fall-through to all V2 (both L2 and L4) Events.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		is_l2 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		is_l4 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
		/* For V1, the hardware can only filter Sync messages or
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
		 * Delay Request messages but not both so fall-through to
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
		 * time stamp all packets.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	case HWTSTAMP_FILTER_ALL:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
		is_l2 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
		is_l4 = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		config->rx_filter = HWTSTAMP_FILTER_ALL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
		return -ERANGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	/* enable/disable Tx h/w time stamping */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	regval = er32(TSYNCTXCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	regval &= ~E1000_TSYNCTXCTL_ENABLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
	regval |= tsync_tx_ctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	ew32(TSYNCTXCTL, regval);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	if ((er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_ENABLED) !=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	    (regval & E1000_TSYNCTXCTL_ENABLED)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
		e_err("Timesync Tx Control register not set as expected\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
		return -EAGAIN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
	/* enable/disable Rx h/w time stamping */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	regval = er32(TSYNCRXCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	regval &= ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	regval |= tsync_rx_ctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
	ew32(TSYNCRXCTL, regval);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
	if ((er32(TSYNCRXCTL) & (E1000_TSYNCRXCTL_ENABLED |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
				 E1000_TSYNCRXCTL_TYPE_MASK)) !=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	    (regval & (E1000_TSYNCRXCTL_ENABLED |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
		       E1000_TSYNCRXCTL_TYPE_MASK))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
		e_err("Timesync Rx Control register not set as expected\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		return -EAGAIN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	/* L2: define ethertype filter for time stamped packets */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	if (is_l2)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
		rxmtrl |= ETH_P_1588;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	/* define which PTP packets get time stamped */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	ew32(RXMTRL, rxmtrl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	/* Filter by destination port */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	if (is_l4) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
		rxudp = PTP_EV_PORT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
		cpu_to_be16s(&rxudp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	ew32(RXUDP, rxudp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	/* Clear TSYNCRXCTL_VALID & TSYNCTXCTL_VALID bit */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	er32(RXSTMPH);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	er32(TXSTMPH);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	/* Get and set the System Time Register SYSTIM base frequency */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	ret_val = e1000e_get_base_timinca(adapter, &regval);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
		return ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	ew32(TIMINCA, regval);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
	/* reset the ns time counter */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
	timecounter_init(&adapter->tc, &adapter->cc,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
			 ktime_to_ns(ktime_get_real()));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
 * e1000_configure - configure the hardware for Rx and Tx
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
 * @adapter: private board structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
static void e1000_configure(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	struct e1000_ring *rx_ring = adapter->rx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	e1000e_set_rx_mode(adapter->netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	e1000_restore_vlan(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	e1000_init_manageability_pt(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	e1000_configure_tx(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
	if (adapter->netdev->features & NETIF_F_RXHASH)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
		e1000e_setup_rss_hash(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	e1000_setup_rctl(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	e1000_configure_rx(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
 * e1000e_power_up_phy - restore link in case the phy was powered down
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
 * @adapter: address of board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
 * The phy may be powered down to save power and turn off link when the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
 * driver is unloaded and wake on lan is not enabled (among others)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
 * *** this routine MUST be followed by a call to e1000e_reset ***
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
void e1000e_power_up_phy(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	if (adapter->hw.phy.ops.power_up)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
		adapter->hw.phy.ops.power_up(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
	adapter->hw.mac.ops.setup_link(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
 * e1000_power_down_phy - Power down the PHY
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
 * Power down the PHY so no link is implied when interface is down.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
 * The PHY cannot be powered down if management or WoL is active.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
static void e1000_power_down_phy(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	/* WoL is enabled */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	if (adapter->wol)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
	if (adapter->hw.phy.ops.power_down)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
		adapter->hw.phy.ops.power_down(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
 * e1000e_reset - bring the hardware into a known good state
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
 * This function boots the hardware and enables some settings that
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
 * require a configuration cycle of the hardware - those cannot be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
 * set/changed during runtime. After reset the device needs to be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
 * properly configured for Rx, Tx etc.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
void e1000e_reset(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
	struct e1000_mac_info *mac = &adapter->hw.mac;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	struct e1000_fc_info *fc = &adapter->hw.fc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	u32 tx_space, min_tx_space, min_rx_space;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	u32 pba = adapter->pba;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
	u16 hwm;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	/* reset Packet Buffer Allocation to default */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	ew32(PBA, pba);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
		/* To maintain wire speed transmits, the Tx FIFO should be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		 * large enough to accommodate two full transmit packets,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
		 * the Rx FIFO should be large enough to accommodate at least
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		 * one full receive packet and is similarly rounded up and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		 * expressed in KB.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		pba = er32(PBA);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
		/* upper 16 bits has Tx packet buffer allocation size in KB */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		tx_space = pba >> 16;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		/* lower 16 bits has Rx packet buffer allocation size in KB */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		pba &= 0xffff;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		/* the Tx fifo also stores 16 bytes of information about the Tx
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
		 * but don't include ethernet FCS because hardware appends it
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
		min_tx_space = (adapter->max_frame_size +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
				sizeof(struct e1000_tx_desc) - ETH_FCS_LEN) * 2;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
		min_tx_space = ALIGN(min_tx_space, 1024);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		min_tx_space >>= 10;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
		/* software strips receive CRC, so leave room for it */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
		min_rx_space = adapter->max_frame_size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
		min_rx_space = ALIGN(min_rx_space, 1024);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		min_rx_space >>= 10;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
		/* If current Tx allocation is less than the min Tx FIFO size,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
		 * and the min Tx FIFO size is less than the current Rx FIFO
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
		 * allocation, take space away from current Rx allocation
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
		if ((tx_space < min_tx_space) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
		    ((min_tx_space - tx_space) < pba)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
			pba -= min_tx_space - tx_space;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
			/* if short on Rx space, Rx wins and must trump Tx
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
			 * adjustment
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
			if (pba < min_rx_space)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
				pba = min_rx_space;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
		ew32(PBA, pba);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	/* flow control settings
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
	 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	 * The high water mark must be low enough to fit one full frame
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	 * (or the size used for early receive) above it in the Rx FIFO.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	 * Set it to the lower of:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	 * - 90% of the Rx FIFO size, and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	 * - the full Rx FIFO size minus one full frame
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
		fc->pause_time = 0xFFFF;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
		fc->pause_time = E1000_FC_PAUSE_TIME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	fc->send_xon = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	fc->current_mode = fc->requested_mode;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
	switch (hw->mac.type) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
	case e1000_ich9lan:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	case e1000_ich10lan:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
			pba = 14;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
			ew32(PBA, pba);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
			fc->high_water = 0x2800;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
			fc->low_water = fc->high_water - 8;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		/* fall-through */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		hwm = min(((pba << 10) * 9 / 10),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
			  ((pba << 10) - adapter->max_frame_size));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		fc->high_water = hwm & E1000_FCRTH_RTH;	/* 8-byte granularity */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		fc->low_water = fc->high_water - 8;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
	case e1000_pchlan:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
		/* Workaround PCH LOM adapter hangs with certain network
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		 * loads.  If hangs persist, try disabling Tx flow control.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
			fc->high_water = 0x3500;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
			fc->low_water = 0x1500;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
			fc->high_water = 0x5000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
			fc->low_water = 0x3000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		fc->refresh_time = 0x1000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	case e1000_pch2lan:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	case e1000_pch_lpt:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
		fc->refresh_time = 0x0400;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
		if (adapter->netdev->mtu <= ETH_DATA_LEN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
			fc->high_water = 0x05C20;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
			fc->low_water = 0x05048;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
			fc->pause_time = 0x0650;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
		pba = 14;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
		ew32(PBA, pba);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
		fc->high_water = ((pba << 10) * 9 / 10) & E1000_FCRTH_RTH;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
		fc->low_water = ((pba << 10) * 8 / 10) & E1000_FCRTL_RTL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	/* Alignment of Tx data is on an arbitrary byte boundary with the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	 * maximum size per Tx descriptor limited only to the transmit
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	 * allocation of the packet buffer minus 96 bytes with an upper
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	 * limit of 24KB due to receive synchronization limitations.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
	adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
				       24 << 10);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	/* Disable Adaptive Interrupt Moderation if 2 full packets cannot
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	 * fit in receive buffer.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	if (adapter->itr_setting & 0x3) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		if ((adapter->max_frame_size * 2) > (pba << 10)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
			if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
				dev_info(&adapter->pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
					 "Interrupt Throttle Rate off\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
				adapter->flags2 |= FLAG2_DISABLE_AIM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
				e1000e_write_itr(adapter, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		} else if (adapter->flags2 & FLAG2_DISABLE_AIM) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
			dev_info(&adapter->pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
				 "Interrupt Throttle Rate on\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
			adapter->flags2 &= ~FLAG2_DISABLE_AIM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
			adapter->itr = 20000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
			e1000e_write_itr(adapter, adapter->itr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	/* Allow time for pending master requests to run */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	mac->ops.reset_hw(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	/* For parts with AMT enabled, let the firmware know
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	 * that the network interface is in control
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	if (adapter->flags & FLAG_HAS_AMT)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		e1000e_get_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	ew32(WUC, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
	if (mac->ops.init_hw(hw))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		e_err("Hardware Error\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	e1000_update_mng_vlan(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
	ew32(VET, ETH_P_8021Q);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	e1000e_reset_adaptive(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	/* initialize systim and reset the ns time counter */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	e1000e_config_hwtstamp(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
	/* Set EEE advertisement as appropriate */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	if (adapter->flags2 & FLAG2_HAS_EEE) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
		s32 ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		u16 adv_addr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
		switch (hw->phy.type) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
		case e1000_phy_82579:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
			adv_addr = I82579_EEE_ADVERTISEMENT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
		case e1000_phy_i217:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
			adv_addr = I217_EEE_ADVERTISEMENT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
		default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
			dev_err(&adapter->pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
				"Invalid PHY type setting EEE advertisement\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
			return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
		ret_val = hw->phy.ops.acquire(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
		if (ret_val) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
			dev_err(&adapter->pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
				"EEE advertisement - unable to acquire PHY\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
			return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		e1000_write_emi_reg_locked(hw, adv_addr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
					   hw->dev_spec.ich8lan.eee_disable ?
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
					   0 : adapter->eee_advert);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		hw->phy.ops.release(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
	if (!netif_running(adapter->netdev) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	    !test_bit(__E1000_TESTING, &adapter->state)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
		e1000_power_down_phy(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	e1000_get_phy_info(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		u16 phy_data = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
		/* speed up time to link by disabling smart power down, ignore
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
		 * the return value of this function because there is nothing
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		 * different we would do if it failed
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
		phy_data &= ~IGP02E1000_PM_SPD;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
int e1000e_up(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	/* hardware has been reset, we need to reload some things */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	e1000_configure(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	clear_bit(__E1000_DOWN, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
	if (adapter->msix_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
		e1000_configure_msix(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
	e1000_irq_enable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	netif_start_queue(adapter->netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	/* fire a link change interrupt to start the watchdog */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
	if (adapter->msix_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
		ew32(ICS, E1000_ICS_LSC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
static void e1000e_flush_descriptors(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	if (!(adapter->flags2 & FLAG2_DMA_BURST))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	/* flush pending descriptor writebacks to memory */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	/* execute the writes immediately */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
	/* due to rare timing issues, write to TIDV/RDTR again to ensure the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	 * write is successful
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
	/* execute the writes immediately */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
static void e1000e_update_stats(struct e1000_adapter *adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
void e1000e_down(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	u32 tctl, rctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	/* signal that we're down so the interrupt handler does not
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
	 * reschedule our watchdog timer
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
	set_bit(__E1000_DOWN, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
	/* disable receives in the hardware */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
	rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
	/* flush and sleep below */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
	netif_stop_queue(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
	/* disable transmits in the hardware */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
	tctl = er32(TCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
	tctl &= ~E1000_TCTL_EN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
	ew32(TCTL, tctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	/* flush both disables and wait for them to finish */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
	usleep_range(10000, 20000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
	e1000_irq_disable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	napi_synchronize(&adapter->napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
	del_timer_sync(&adapter->watchdog_timer);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
	del_timer_sync(&adapter->phy_info_timer);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	netif_carrier_off(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	spin_lock(&adapter->stats64_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	e1000e_update_stats(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	spin_unlock(&adapter->stats64_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
	e1000e_flush_descriptors(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
	e1000_clean_tx_ring(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	e1000_clean_rx_ring(adapter->rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	adapter->link_speed = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
	adapter->link_duplex = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	/* Disable Si errata workaround on PCHx for jumbo frame flow */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
	if ((hw->mac.type >= e1000_pch2lan) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	    (adapter->netdev->mtu > ETH_DATA_LEN) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
	    e1000_lv_jumbo_workaround_ich8lan(hw, false))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
		e_dbg("failed to disable jumbo frame workaround mode\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
	if (!pci_channel_offline(adapter->pdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
		e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
	/* TODO: for power management, we could drop the link and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	 * pci_disable_device here.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
void e1000e_reinit_locked(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
	might_sleep();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
		usleep_range(1000, 2000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	e1000e_down(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	e1000e_up(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
	clear_bit(__E1000_RESETTING, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
 * e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
 * @cc: cyclecounter structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
						     cc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
	cycle_t systim;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
	/* latch SYSTIMH on read of SYSTIML */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
	systim = (cycle_t)er32(SYSTIML);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
	systim |= (cycle_t)er32(SYSTIMH) << 32;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	return systim;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
 * @adapter: board private structure to initialize
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
 * e1000_sw_init initializes the Adapter private data structure.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
 * Fields are initialized based on PCI device information and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
 * OS network device settings (MTU size).
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
static int e1000_sw_init(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	adapter->rx_ps_bsize0 = 128;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	adapter->tx_ring_count = E1000_DEFAULT_TXD;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	adapter->rx_ring_count = E1000_DEFAULT_RXD;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
	spin_lock_init(&adapter->stats64_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	e1000e_set_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	if (e1000_alloc_queues(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
		return -ENOMEM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	/* Setup hardware time stamping cyclecounter */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
	if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		adapter->cc.read = e1000e_cyclecounter_read;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
		adapter->cc.mask = CLOCKSOURCE_MASK(64);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		adapter->cc.mult = 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
		/* cc.shift set in e1000e_get_base_tininca() */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
		spin_lock_init(&adapter->systim_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		INIT_WORK(&adapter->tx_hwtstamp_work, e1000e_tx_hwtstamp_work);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	/* Explicitly disable IRQ since the NIC can be in any state. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
	e1000_irq_disable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
	set_bit(__E1000_DOWN, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
 * e1000_intr_msi_test - Interrupt Handler
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
 * @irq: interrupt number
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
 * @data: pointer to a network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
static irqreturn_t e1000_intr_msi_test(int __always_unused irq, void *data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	struct net_device *netdev = data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	u32 icr = er32(ICR);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
	e_dbg("icr is %08X\n", icr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
	if (icr & E1000_ICR_RXSEQ) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
		/* Force memory writes to complete before acknowledging the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
		 * interrupt is handled.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		wmb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
	return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
 * e1000_test_msi_interrupt - Returns 0 for successful test
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
 * @adapter: board private struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
 * code flow taken from tg3.c
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
	int err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
	/* poll_enable hasn't been called yet, so don't need disable */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
	/* clear any pending events */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
	er32(ICR);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
	/* free the real vector and request a test handler */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
	e1000_free_irq(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
	e1000e_reset_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
	/* Assume that the test fails, if it succeeds then the test
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
	 * MSI irq handler will unset this flag
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
	adapter->flags |= FLAG_MSI_TEST_FAILED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
	err = pci_enable_msi(adapter->pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		goto msi_test_failed;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
			  netdev->name, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
	if (err) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		pci_disable_msi(adapter->pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
		goto msi_test_failed;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
	/* Force memory writes to complete before enabling and firing an
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	 * interrupt.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	wmb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	e1000_irq_enable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	/* fire an unusual interrupt on the test handler */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	ew32(ICS, E1000_ICS_RXSEQ);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
	e1e_flush();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
	msleep(100);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
	e1000_irq_disable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
	rmb();			/* read flags after interrupt has been fired */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		e_info("MSI interrupt test failed, using legacy interrupt.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
		e_dbg("MSI interrupt test succeeded!\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
	free_irq(adapter->pdev->irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	pci_disable_msi(adapter->pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
msi_test_failed:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	e1000e_set_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	return e1000_request_irq(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
 * @adapter: board private struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
 * code flow taken from tg3.c, called with e1000 interrupts disabled.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
static int e1000_test_msi(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	int err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	u16 pci_cmd;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	if (!(adapter->flags & FLAG_MSI_ENABLED))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	/* disable SERR in case the MSI write causes a master abort */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	if (pci_cmd & PCI_COMMAND_SERR)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
		pci_write_config_word(adapter->pdev, PCI_COMMAND,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
				      pci_cmd & ~PCI_COMMAND_SERR);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
	err = e1000_test_msi_interrupt(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
	/* re-enable SERR */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
	if (pci_cmd & PCI_COMMAND_SERR) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
		pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
		pci_cmd |= PCI_COMMAND_SERR;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
		pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
	return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
 * e1000_open - Called when a network interface is made active
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
 * Returns 0 on success, negative value on failure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
 * The open entry point is called when a network interface is made
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
 * active by the system (IFF_UP).  At this point all resources needed
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
 * for transmit and receive operations are allocated, the interrupt
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
 * handler is registered with the OS, the watchdog timer is started,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
 * and the stack is notified that the interface is ready.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
static int e1000_open(struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	int err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	/* disallow open during test */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	if (test_bit(__E1000_TESTING, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
		return -EBUSY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	pm_runtime_get_sync(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
	netif_carrier_off(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
	/* allocate transmit descriptors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
	err = e1000e_setup_tx_resources(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		goto err_setup_tx;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
	/* allocate receive descriptors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
	err = e1000e_setup_rx_resources(adapter->rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		goto err_setup_rx;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	/* If AMT is enabled, let the firmware know that the network
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	 * interface is now open and reset the part to a known state.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
	if (adapter->flags & FLAG_HAS_AMT) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		e1000e_get_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
		e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
	e1000e_power_up_phy(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
	if ((adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		e1000_update_mng_vlan(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
	/* DMA latency requirement to workaround jumbo issue */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
	pm_qos_add_request(&adapter->netdev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
			   PM_QOS_DEFAULT_VALUE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
	/* before we allocate an interrupt, we must be ready to handle it.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
	 * as soon as we call pci_request_irq, so we have to setup our
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	 * clean_rx handler before we do so.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	e1000_configure(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	err = e1000_request_irq(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
		goto err_req_irq;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	/* Work around PCIe errata with MSI interrupts causing some chipsets to
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
	 * ignore e1000e MSI messages, which means we need to test our MSI
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
	 * interrupt now
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
	if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		err = e1000_test_msi(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
		if (err) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
			e_err("Interrupt allocation failed\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
			goto err_req_irq;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
	/* From here on the code is the same as e1000e_up() */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
	clear_bit(__E1000_DOWN, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	napi_enable(&adapter->napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
	e1000_irq_enable(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
	adapter->tx_hang_recheck = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
	netif_start_queue(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
	adapter->idle_check = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	hw->mac.get_link_status = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
	pm_runtime_put(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
	/* fire a link status change interrupt to start the watchdog */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	if (adapter->msix_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		ew32(ICS, E1000_ICS_LSC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
err_req_irq:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	e1000e_release_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	e1000_power_down_phy(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	e1000e_free_rx_resources(adapter->rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
err_setup_rx:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
	e1000e_free_tx_resources(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
err_setup_tx:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	pm_runtime_put_sync(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
	return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
 * e1000_close - Disables a network interface
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
 * Returns 0, this is not allowed to fail
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
 * The close entry point is called when an interface is de-activated
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
 * by the OS.  The hardware is still under the drivers control, but
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
 * needs to be disabled.  A global MAC reset is issued to stop the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
 * hardware, and all transmit and receive resources are freed.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
static int e1000_close(struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	int count = E1000_CHECK_RESET_COUNT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		usleep_range(10000, 20000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	pm_runtime_get_sync(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
	if (!test_bit(__E1000_DOWN, &adapter->state)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		e1000e_down(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
		e1000_free_irq(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	napi_disable(&adapter->napi);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	e1000_power_down_phy(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	e1000e_free_tx_resources(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	e1000e_free_rx_resources(adapter->rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
	/* kill manageability vlan ID if supported, but not if a vlan with
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	 * the same ID is registered on the host OS (let 8021q kill it)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
				       adapter->mng_vlan_id);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	/* If AMT is enabled, let the firmware know that the network
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
	 * interface is now closed
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	if ((adapter->flags & FLAG_HAS_AMT) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	    !test_bit(__E1000_TESTING, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
		e1000e_release_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	pm_qos_remove_request(&adapter->netdev->pm_qos_req);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	pm_runtime_put_sync(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
 * e1000_set_mac - Change the Ethernet Address of the NIC
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
 * @p: pointer to an address structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
 * Returns 0 on success, negative on failure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
static int e1000_set_mac(struct net_device *netdev, void *p)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	struct sockaddr *addr = p;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
	if (!is_valid_ether_addr(addr->sa_data))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
		return -EADDRNOTAVAIL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
	hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
		/* activate the work around */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		e1000e_set_laa_state_82571(&adapter->hw, 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
		/* Hold a copy of the LAA in RAR[14] This is done so that
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
		 * between the time RAR[0] gets clobbered  and the time it
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
		 * of the RARs and no incoming packets directed to this port
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
		 * are dropped. Eventually the LAA will be in RAR[0] and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
		 * RAR[14]
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
		hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
				    adapter->hw.mac.rar_entry_count - 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
 * e1000e_update_phy_task - work thread to update phy
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
 * @work: pointer to our work struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
 * this worker thread exists because we must acquire a
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
 * semaphore to read the phy, which we could msleep while
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
 * waiting for it, and we can't msleep in a timer.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
static void e1000e_update_phy_task(struct work_struct *work)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	struct e1000_adapter *adapter = container_of(work,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
						     struct e1000_adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
						     update_phy_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
	if (test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
	e1000_get_phy_info(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
 * e1000_update_phy_info - timre call-back to update PHY info
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
 * @data: pointer to adapter cast into an unsigned long
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
 * Need to wait a few seconds after link up to get diagnostic information from
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
 * the phy
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
static void e1000_update_phy_info(unsigned long data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	if (test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
	schedule_work(&adapter->update_phy_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
 * e1000e_update_phy_stats - Update the PHY statistics counters
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
 * Read/clear the upper 16-bit PHY registers and read/accumulate lower
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
static void e1000e_update_phy_stats(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
	s32 ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
	u16 phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
	ret_val = hw->phy.ops.acquire(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
	if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	/* A page set is expensive so check if already on desired page.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
	 * If not, set to the page with the PHY status registers.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	hw->phy.addr = 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
	ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
					   &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
		goto release;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
	if (phy_data != (HV_STATS_PAGE << IGP_PAGE_SHIFT)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		ret_val = hw->phy.ops.set_page(hw,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
					       HV_STATS_PAGE << IGP_PAGE_SHIFT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
		if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
			goto release;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	/* Single Collision Count */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
	ret_val = hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
	if (!ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		adapter->stats.scc += phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
	/* Excessive Collision Count */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	ret_val = hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	if (!ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
		adapter->stats.ecol += phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
	/* Multiple Collision Count */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	ret_val = hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	if (!ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
		adapter->stats.mcc += phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	/* Late Collision Count */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	ret_val = hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	if (!ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
		adapter->stats.latecol += phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	/* Collision Count - also used for adaptive IFS */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
	ret_val = hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
	if (!ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
		hw->mac.collision_delta = phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	/* Defer Count */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	ret_val = hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	if (!ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		adapter->stats.dc += phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	/* Transmit with no CRS */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	ret_val = hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	if (!ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		adapter->stats.tncrs += phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
release:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	hw->phy.ops.release(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
 * e1000e_update_stats - Update the board statistics counters
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
static void e1000e_update_stats(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	/* Prevent stats update while adapter is being reset, or if the pci
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	 * connection is down.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	if (adapter->link_speed == 0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
	if (pci_channel_offline(pdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	adapter->stats.crcerrs += er32(CRCERRS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	adapter->stats.gprc += er32(GPRC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	adapter->stats.gorc += er32(GORCL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	er32(GORCH);		/* Clear gorc */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	adapter->stats.bprc += er32(BPRC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
	adapter->stats.mprc += er32(MPRC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	adapter->stats.roc += er32(ROC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	adapter->stats.mpc += er32(MPC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	/* Half-duplex statistics */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	if (adapter->link_duplex == HALF_DUPLEX) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
		if (adapter->flags2 & FLAG2_HAS_PHY_STATS) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
			e1000e_update_phy_stats(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
			adapter->stats.scc += er32(SCC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
			adapter->stats.ecol += er32(ECOL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
			adapter->stats.mcc += er32(MCC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
			adapter->stats.latecol += er32(LATECOL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
			adapter->stats.dc += er32(DC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
			hw->mac.collision_delta = er32(COLC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
			if ((hw->mac.type != e1000_82574) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
			    (hw->mac.type != e1000_82583))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
				adapter->stats.tncrs += er32(TNCRS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
		adapter->stats.colc += hw->mac.collision_delta;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	adapter->stats.xonrxc += er32(XONRXC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	adapter->stats.xontxc += er32(XONTXC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	adapter->stats.xoffrxc += er32(XOFFRXC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
	adapter->stats.xofftxc += er32(XOFFTXC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	adapter->stats.gptc += er32(GPTC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	adapter->stats.gotc += er32(GOTCL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	er32(GOTCH);		/* Clear gotc */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	adapter->stats.rnbc += er32(RNBC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	adapter->stats.ruc += er32(RUC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	adapter->stats.mptc += er32(MPTC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	adapter->stats.bptc += er32(BPTC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	/* used for adaptive IFS */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	hw->mac.tx_packet_delta = er32(TPT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
	adapter->stats.tpt += hw->mac.tx_packet_delta;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
	adapter->stats.algnerrc += er32(ALGNERRC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	adapter->stats.rxerrc += er32(RXERRC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	adapter->stats.cexterr += er32(CEXTERR);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	adapter->stats.tsctc += er32(TSCTC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
	adapter->stats.tsctfc += er32(TSCTFC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
	/* Fill out the OS statistics structure */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
	netdev->stats.multicast = adapter->stats.mprc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	netdev->stats.collisions = adapter->stats.colc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
	/* Rx Errors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	/* RLEC on some newer hardware can be incorrect so build
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
	 * our own version based on RUC and ROC
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	netdev->stats.rx_errors = adapter->stats.rxerrc +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	    adapter->stats.crcerrs + adapter->stats.algnerrc +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	    adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	netdev->stats.rx_length_errors = adapter->stats.ruc +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
	    adapter->stats.roc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
	/* Tx Errors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	netdev->stats.tx_errors = adapter->stats.ecol + adapter->stats.latecol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
	netdev->stats.tx_window_errors = adapter->stats.latecol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
	/* Tx Dropped needs to be maintained elsewhere */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
	/* Management Stats */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	adapter->stats.mgptc += er32(MGTPTC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	adapter->stats.mgprc += er32(MGTPRC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	adapter->stats.mgpdc += er32(MGTPDC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
	/* Correctable ECC Errors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	if (hw->mac.type == e1000_pch_lpt) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
		u32 pbeccsts = er32(PBECCSTS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
		adapter->corr_errors +=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		adapter->uncorr_errors +=
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
 * e1000_phy_read_status - Update the PHY register status snapshot
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
 * @adapter: board private structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
static void e1000_phy_read_status(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
	struct e1000_phy_regs *phy = &adapter->phy_regs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
	if (!pm_runtime_suspended((&adapter->pdev->dev)->parent) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
	    (er32(STATUS) & E1000_STATUS_LU) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
		int ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
		ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
		ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
		ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
		ret_val |= e1e_rphy(hw, MII_LPA, &phy->lpa);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
		ret_val |= e1e_rphy(hw, MII_EXPANSION, &phy->expansion);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		ret_val |= e1e_rphy(hw, MII_CTRL1000, &phy->ctrl1000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
		ret_val |= e1e_rphy(hw, MII_STAT1000, &phy->stat1000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
		ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
		if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
			e_warn("Error reading PHY register\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
		/* Do not read PHY registers if link is not up
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
		 * Set values to typical power-on defaults
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
			     BMSR_ERCAP);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
				  ADVERTISE_ALL | ADVERTISE_CSMA);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		phy->lpa = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		phy->expansion = EXPANSION_ENABLENPAGE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
		phy->ctrl1000 = ADVERTISE_1000FULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		phy->stat1000 = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
static void e1000_print_link_info(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	u32 ctrl = er32(CTRL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	/* Link status message must follow this format for user tools */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	pr_info("%s NIC Link is Up %d Mbps %s Duplex, Flow Control: %s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
		adapter->netdev->name, adapter->link_speed,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
		(ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE) ? "Rx/Tx" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
		(ctrl & E1000_CTRL_RFCE) ? "Rx" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
		(ctrl & E1000_CTRL_TFCE) ? "Tx" : "None");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
static bool e1000e_has_link(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	bool link_active = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	s32 ret_val = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	/* get_link_status is set on LSC (link status) interrupt or
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	 * Rx sequence error interrupt.  get_link_status will stay
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	 * false until the check_for_link establishes link
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	 * for copper adapters ONLY
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	switch (hw->phy.media_type) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	case e1000_media_type_copper:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
		if (hw->mac.get_link_status) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
			ret_val = hw->mac.ops.check_for_link(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
			link_active = !hw->mac.get_link_status;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
			link_active = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	case e1000_media_type_fiber:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
		ret_val = hw->mac.ops.check_for_link(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	case e1000_media_type_internal_serdes:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
		ret_val = hw->mac.ops.check_for_link(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
		link_active = adapter->hw.mac.serdes_has_link;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	case e1000_media_type_unknown:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
		e_info("Gigabit has been disabled, downgrading speed\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	return link_active;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
static void e1000e_enable_receives(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	/* make sure the receive unit is started */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
	    (adapter->flags & FLAG_RESTART_NOW)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
		struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		u32 rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
		ew32(RCTL, rctl | E1000_RCTL_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
		adapter->flags &= ~FLAG_RESTART_NOW;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	/* With 82574 controllers, PHY needs to be checked periodically
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
	 * for hung state and reset, if two calls return true
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	if (e1000_check_phy_82574(hw))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
		adapter->phy_hang_count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
		adapter->phy_hang_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	if (adapter->phy_hang_count > 1) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
		adapter->phy_hang_count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
		schedule_work(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
 * e1000_watchdog - Timer Call-back
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
 * @data: pointer to adapter cast into an unsigned long
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
static void e1000_watchdog(unsigned long data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	/* Do the rest outside of interrupt context */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	schedule_work(&adapter->watchdog_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
	/* TODO: make this use queue_delayed_work() */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
static void e1000_watchdog_task(struct work_struct *work)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
	struct e1000_adapter *adapter = container_of(work,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
						     struct e1000_adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
						     watchdog_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
	struct e1000_mac_info *mac = &adapter->hw.mac;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
	struct e1000_phy_info *phy = &adapter->hw.phy;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
	struct e1000_ring *tx_ring = adapter->tx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
	u32 link, tctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
	if (test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
	link = e1000e_has_link(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
	if ((netif_carrier_ok(netdev)) && link) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
		/* Cancel scheduled suspend requests. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
		pm_runtime_resume(netdev->dev.parent);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
		e1000e_enable_receives(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
		goto link_up;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
		e1000_update_mng_vlan(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	if (link) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
		if (!netif_carrier_ok(netdev)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
			bool txb2b = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
			/* Cancel scheduled suspend requests. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
			pm_runtime_resume(netdev->dev.parent);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
			/* update snapshot of PHY registers on LSC */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
			e1000_phy_read_status(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
			mac->ops.get_link_up_info(&adapter->hw,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
						  &adapter->link_speed,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
						  &adapter->link_duplex);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
			e1000_print_link_info(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
			/* check if SmartSpeed worked */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
			e1000e_check_downshift(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
			if (phy->speed_downgraded)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
				netdev_warn(netdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
					    "Link Speed was downgraded by SmartSpeed\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
			/* On supported PHYs, check for duplex mismatch only
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
			 * if link has autonegotiated at 10/100 half
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
			if ((hw->phy.type == e1000_phy_igp_3 ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
			     hw->phy.type == e1000_phy_bm) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
			    hw->mac.autoneg &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
			    (adapter->link_speed == SPEED_10 ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
			     adapter->link_speed == SPEED_100) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
			    (adapter->link_duplex == HALF_DUPLEX)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
				u16 autoneg_exp;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
				e1e_rphy(hw, MII_EXPANSION, &autoneg_exp);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
				if (!(autoneg_exp & EXPANSION_NWAY))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
					e_info("Autonegotiated half duplex but link partner cannot autoneg.  Try forcing full duplex if link gets many collisions.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
			/* adjust timeout factor according to speed/duplex */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
			adapter->tx_timeout_factor = 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
			switch (adapter->link_speed) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
			case SPEED_10:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
				txb2b = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
				adapter->tx_timeout_factor = 16;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
			case SPEED_100:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
				txb2b = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
				adapter->tx_timeout_factor = 10;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
				break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
			/* workaround: re-program speed mode bit after
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
			 * link-up event
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
			    !txb2b) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
				u32 tarc0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
				tarc0 = er32(TARC(0));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
				tarc0 &= ~SPEED_MODE_BIT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
				ew32(TARC(0), tarc0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
			/* disable TSO for pcie and 10/100 speeds, to avoid
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
			 * some hardware issues
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
				switch (adapter->link_speed) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
				case SPEED_10:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
				case SPEED_100:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
					e_info("10/100 speed: disabling TSO\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
					netdev->features &= ~NETIF_F_TSO;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
					netdev->features &= ~NETIF_F_TSO6;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
					break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
				case SPEED_1000:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
					netdev->features |= NETIF_F_TSO;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
					netdev->features |= NETIF_F_TSO6;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
					break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
				default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
					/* oops */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
					break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
				}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
			/* enable transmits in the hardware, need to do this
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
			 * after setting TARC(0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
			tctl = er32(TCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
			tctl |= E1000_TCTL_EN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
			ew32(TCTL, tctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
			/* Perform any post-link-up configuration before
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
			 * reporting link up.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
			if (phy->ops.cfg_on_link_up)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
				phy->ops.cfg_on_link_up(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
			netif_carrier_on(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
			if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
				mod_timer(&adapter->phy_info_timer,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
					  round_jiffies(jiffies + 2 * HZ));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
		if (netif_carrier_ok(netdev)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
			adapter->link_speed = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
			adapter->link_duplex = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
			/* Link status message must follow this format */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
			pr_info("%s NIC Link is Down\n", adapter->netdev->name);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
			netif_carrier_off(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
			if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
				mod_timer(&adapter->phy_info_timer,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
					  round_jiffies(jiffies + 2 * HZ));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
			/* The link is lost so the controller stops DMA.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
			 * If there is queued Tx work that cannot be done
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
			 * or if on an 8000ES2LAN which requires a Rx packet
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
			 * buffer work-around on link down event, reset the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
			 * controller to flush the Tx/Rx packet buffers.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
			 * (Do the reset outside of interrupt context).
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
			if ((adapter->flags & FLAG_RX_NEEDS_RESTART) ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
			    (e1000_desc_unused(tx_ring) + 1 < tx_ring->count))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
				adapter->flags |= FLAG_RESTART_NOW;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
				pm_schedule_suspend(netdev->dev.parent,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
						    LINK_TIMEOUT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
link_up:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
	spin_lock(&adapter->stats64_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
	e1000e_update_stats(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
	adapter->tpt_old = adapter->stats.tpt;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
	adapter->colc_old = adapter->stats.colc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
	adapter->gorc_old = adapter->stats.gorc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
	adapter->gotc_old = adapter->stats.gotc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	spin_unlock(&adapter->stats64_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	if (adapter->flags & FLAG_RESTART_NOW) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
		schedule_work(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
		/* return immediately since reset is imminent */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
	e1000e_update_adaptive(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
	/* Simple mode for Interrupt Throttle Rate (ITR) */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
	if (adapter->itr_setting == 4) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
		/* Symmetric Tx/Rx gets a reduced ITR=2000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
		 * Total asymmetrical Tx or Rx gets ITR=8000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
		 * everyone else is between 2000-8000.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		u32 goc = (adapter->gotc + adapter->gorc) / 10000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
		u32 dif = (adapter->gotc > adapter->gorc ?
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
			   adapter->gotc - adapter->gorc :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
			   adapter->gorc - adapter->gotc) / 10000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
		e1000e_write_itr(adapter, itr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
	/* Cause software interrupt to ensure Rx ring is cleaned */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
	if (adapter->msix_entries)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
		ew32(ICS, adapter->rx_ring->ims_val);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
		ew32(ICS, E1000_ICS_RXDMT0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
	/* flush pending descriptors to memory before detecting Tx hang */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
	e1000e_flush_descriptors(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
	/* Force detection of hung controller every watchdog period */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	adapter->detect_tx_hung = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
	/* With 82571 controllers, LAA may be overwritten due to controller
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	 * reset from the other port. Set the appropriate LAA in RAR[0]
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
	if (e1000e_get_laa_state_82571(hw))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
		hw->mac.ops.rar_set(hw, adapter->hw.mac.addr, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	if (adapter->flags2 & FLAG2_CHECK_PHY_HANG)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
		e1000e_check_82574_phy_workaround(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
	/* Clear valid timestamp stuck in RXSTMPL/H due to a Rx error */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	if (adapter->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
		if ((adapter->flags2 & FLAG2_CHECK_RX_HWTSTAMP) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
		    (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
			er32(RXSTMPH);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
			adapter->rx_hwtstamp_cleared++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
			adapter->flags2 |= FLAG2_CHECK_RX_HWTSTAMP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
	/* Reset the timer */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	if (!test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
		mod_timer(&adapter->watchdog_timer,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
			  round_jiffies(jiffies + 2 * HZ));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
#define E1000_TX_FLAGS_CSUM		0x00000001
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
#define E1000_TX_FLAGS_VLAN		0x00000002
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
#define E1000_TX_FLAGS_TSO		0x00000004
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
#define E1000_TX_FLAGS_IPV4		0x00000008
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
#define E1000_TX_FLAGS_NO_FCS		0x00000010
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
#define E1000_TX_FLAGS_HWTSTAMP		0x00000020
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
#define E1000_TX_FLAGS_VLAN_SHIFT	16
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
	struct e1000_context_desc *context_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	u32 cmd_length = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
	u16 ipcse = 0, mss;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	if (!skb_is_gso(skb))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	if (skb_header_cloned(skb)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
		int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
		if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
			return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	mss = skb_shinfo(skb)->gso_size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
	if (skb->protocol == htons(ETH_P_IP)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
		struct iphdr *iph = ip_hdr(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
		iph->tot_len = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		iph->check = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
							 0, IPPROTO_TCP, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		cmd_length = E1000_TXD_CMD_IP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
		ipcse = skb_transport_offset(skb) - 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	} else if (skb_is_gso_v6(skb)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
		ipv6_hdr(skb)->payload_len = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
						       &ipv6_hdr(skb)->daddr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
						       0, IPPROTO_TCP, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
		ipcse = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	ipcss = skb_network_offset(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
	tucss = skb_transport_offset(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
		       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	i = tx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
	buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	context_desc->lower_setup.ip_fields.ipcss = ipcss;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
	context_desc->lower_setup.ip_fields.ipcso = ipcso;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
	context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	context_desc->upper_setup.tcp_fields.tucss = tucss;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
	context_desc->upper_setup.tcp_fields.tucso = tucso;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
	context_desc->upper_setup.tcp_fields.tucse = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	buffer_info->time_stamp = jiffies;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
	buffer_info->next_to_watch = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
	i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
	if (i == tx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
		i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
	tx_ring->next_to_use = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	return 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
	struct e1000_context_desc *context_desc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
	u8 css;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	u32 cmd_len = E1000_TXD_CMD_DEXT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
	__be16 protocol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
	if (skb->ip_summed != CHECKSUM_PARTIAL)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
		protocol = skb->protocol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
	switch (protocol) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
	case cpu_to_be16(ETH_P_IP):
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
			cmd_len |= E1000_TXD_CMD_TCP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
	case cpu_to_be16(ETH_P_IPV6):
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
		/* XXX not handling all IPV6 headers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
			cmd_len |= E1000_TXD_CMD_TCP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
		if (unlikely(net_ratelimit()))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
			e_warn("checksum_partial proto=%x!\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
			       be16_to_cpu(protocol));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	css = skb_checksum_start_offset(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
	i = tx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
	buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
	context_desc->lower_setup.ip_config = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
	context_desc->upper_setup.tcp_fields.tucss = css;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
	context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
	context_desc->upper_setup.tcp_fields.tucse = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
	context_desc->tcp_seg_setup.data = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	buffer_info->time_stamp = jiffies;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
	buffer_info->next_to_watch = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
	i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
	if (i == tx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
		i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
	tx_ring->next_to_use = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
	return 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
			unsigned int first, unsigned int max_per_txd,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
			unsigned int nr_frags)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
	struct pci_dev *pdev = adapter->pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
	unsigned int len = skb_headlen(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
	unsigned int offset = 0, size, count = 0, i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
	unsigned int f, bytecount, segs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
	i = tx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
	while (len) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
		buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
		size = min(len, max_per_txd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
		buffer_info->length = size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
		buffer_info->time_stamp = jiffies;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
		buffer_info->next_to_watch = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
		buffer_info->dma = dma_map_single(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
						  skb->data + offset,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
						  size, DMA_TO_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
		buffer_info->mapped_as_page = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
			goto dma_error;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
		len -= size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
		offset += size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
		count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
		if (len) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
			i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
			if (i == tx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
				i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	for (f = 0; f < nr_frags; f++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
		const struct skb_frag_struct *frag;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
		frag = &skb_shinfo(skb)->frags[f];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
		len = skb_frag_size(frag);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
		offset = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
		while (len) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
			i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
			if (i == tx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
				i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
			buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
			size = min(len, max_per_txd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
			buffer_info->length = size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
			buffer_info->time_stamp = jiffies;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
			buffer_info->next_to_watch = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
							    offset, size,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
							    DMA_TO_DEVICE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
			buffer_info->mapped_as_page = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
				goto dma_error;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
			len -= size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
			offset += size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
			count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
	segs = skb_shinfo(skb)->gso_segs ? : 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
	/* multiply data chunks by size of headers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
	tx_ring->buffer_info[i].skb = skb;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	tx_ring->buffer_info[i].segs = segs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
	tx_ring->buffer_info[i].bytecount = bytecount;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	tx_ring->buffer_info[first].next_to_watch = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	return count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
dma_error:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
	dev_err(&pdev->dev, "Tx DMA map failed\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
	buffer_info->dma = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
	if (count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
		count--;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
	while (count--) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
		if (i == 0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
			i += tx_ring->count;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
		i--;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
		buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
		e1000_put_txbuf(tx_ring, buffer_info);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
	struct e1000_tx_desc *tx_desc = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
	struct e1000_buffer *buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
	unsigned int i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
	if (tx_flags & E1000_TX_FLAGS_TSO) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
		    E1000_TXD_CMD_TSE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
		if (tx_flags & E1000_TX_FLAGS_IPV4)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
		txd_lower |= E1000_TXD_CMD_VLE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
		txd_lower &= ~(E1000_TXD_CMD_IFCS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
	if (unlikely(tx_flags & E1000_TX_FLAGS_HWTSTAMP)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
		txd_upper |= E1000_TXD_EXTCMD_TSTAMP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
	i = tx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
	do {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
		buffer_info = &tx_ring->buffer_info[i];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
		tx_desc = E1000_TX_DESC(*tx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
		tx_desc->lower.data = cpu_to_le32(txd_lower |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
						  buffer_info->length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
		tx_desc->upper.data = cpu_to_le32(txd_upper);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
		i++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
		if (i == tx_ring->count)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
			i = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	} while (--count > 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
	/* Force memory writes to complete before letting h/w
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
	 * know there are new descriptors to fetch.  (Only
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
	 * applicable for weak-ordered memory model archs,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
	 * such as IA-64).
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
	wmb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
	tx_ring->next_to_use = i;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
		e1000e_update_tdt_wa(tx_ring, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
		writel(i, tx_ring->tail);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
	/* we need this if more than one processor can write to our tail
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
	 * at a time, it synchronizes IO on IA64/Altix systems
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
	mmiowb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
#define MINIMUM_DHCP_PACKET_SIZE 282
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
				    struct sk_buff *skb)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
	u16 length, offset;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
	if (vlan_tx_tag_present(skb) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
	    !((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
	      (adapter->hw.mng_cookie.status &
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
	       E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
	if (((struct ethhdr *)skb->data)->h_proto != htons(ETH_P_IP))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
	{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
		const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data + 14);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
		struct udphdr *udp;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
		if (ip->protocol != IPPROTO_UDP)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
			return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
		if (ntohs(udp->dest) != 67)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
			return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
		offset = (u8 *)udp + 8 - skb->data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
		length = skb->len - offset;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
		return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
	struct e1000_adapter *adapter = tx_ring->adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
	netif_stop_queue(adapter->netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
	/* Herbert's original patch had:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
	 *  smp_mb__after_netif_stop_queue();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
	 * but since that doesn't exist yet, just open code it.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
	smp_mb();
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
	/* We need to check again in a case another CPU has just
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
	 * made room available.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
	if (e1000_desc_unused(tx_ring) < size)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
		return -EBUSY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
	/* A reprieve! */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
	netif_start_queue(adapter->netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	++adapter->restart_queue;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
	BUG_ON(size > tx_ring->count);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
	if (e1000_desc_unused(tx_ring) >= size)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
	return __e1000_maybe_stop_tx(tx_ring, size);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
				    struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
	struct e1000_ring *tx_ring = adapter->tx_ring;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	unsigned int first;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
	unsigned int tx_flags = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
	unsigned int len = skb_headlen(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
	unsigned int nr_frags;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	unsigned int mss;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
	int count = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
	int tso;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
	unsigned int f;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
	if (test_bit(__E1000_DOWN, &adapter->state)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
		dev_kfree_skb_any(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
		return NETDEV_TX_OK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
	if (skb->len <= 0) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
		dev_kfree_skb_any(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
		return NETDEV_TX_OK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
	/* The minimum packet size with TCTL.PSP set is 17 bytes so
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
	 * pad skb in order to meet this minimum size requirement
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
	if (unlikely(skb->len < 17)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
		if (skb_pad(skb, 17 - skb->len))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
			return NETDEV_TX_OK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
		skb->len = 17;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
		skb_set_tail_pointer(skb, 17);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
	mss = skb_shinfo(skb)->gso_size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
	if (mss) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
		u8 hdr_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
		 * points to just header, pull a few bytes of payload from
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
		 * frags into skb->data
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
		/* we do this workaround for ES2LAN, but it is un-necessary,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
		 * avoiding it could save a lot of cycles
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
		if (skb->data_len && (hdr_len == len)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
			unsigned int pull_size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
			pull_size = min_t(unsigned int, 4, skb->data_len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
			if (!__pskb_pull_tail(skb, pull_size)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
				e_err("__pskb_pull_tail failed.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
				dev_kfree_skb_any(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
				return NETDEV_TX_OK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
			len = skb_headlen(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
	/* reserve a descriptor for the offload context */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
		count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
	count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
	count += DIV_ROUND_UP(len, adapter->tx_fifo_limit);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	nr_frags = skb_shinfo(skb)->nr_frags;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
	for (f = 0; f < nr_frags; f++)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
		count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
				      adapter->tx_fifo_limit);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
	if (adapter->hw.mac.tx_pkt_filtering)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
		e1000_transfer_dhcp_info(adapter, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
	/* need: count + 2 desc gap to keep tail from touching
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
	 * head, otherwise try next time
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	if (e1000_maybe_stop_tx(tx_ring, count + 2))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
		return NETDEV_TX_BUSY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
	if (vlan_tx_tag_present(skb)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
		tx_flags |= E1000_TX_FLAGS_VLAN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
	first = tx_ring->next_to_use;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
	tso = e1000_tso(tx_ring, skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
	if (tso < 0) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
		dev_kfree_skb_any(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
		return NETDEV_TX_OK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
	if (tso)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
		tx_flags |= E1000_TX_FLAGS_TSO;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
	else if (e1000_tx_csum(tx_ring, skb))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
		tx_flags |= E1000_TX_FLAGS_CSUM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	 * no longer assume, we must.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
	if (skb->protocol == htons(ETH_P_IP))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
		tx_flags |= E1000_TX_FLAGS_IPV4;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
	if (unlikely(skb->no_fcs))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
		tx_flags |= E1000_TX_FLAGS_NO_FCS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
	/* if count is 0 then mapping error has occurred */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
	count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
			     nr_frags);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
	if (count) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
		if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
			     !adapter->tx_hwtstamp_skb)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
			tx_flags |= E1000_TX_FLAGS_HWTSTAMP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
			adapter->tx_hwtstamp_skb = skb_get(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
			schedule_work(&adapter->tx_hwtstamp_work);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
			skb_tx_timestamp(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
		netdev_sent_queue(netdev, skb->len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
		e1000_tx_queue(tx_ring, tx_flags, count);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
		/* Make sure there is space in the ring for the next send. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
		e1000_maybe_stop_tx(tx_ring,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
				    (MAX_SKB_FRAGS *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
				     DIV_ROUND_UP(PAGE_SIZE,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
						  adapter->tx_fifo_limit) + 2));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
		dev_kfree_skb_any(skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
		tx_ring->buffer_info[first].time_stamp = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
		tx_ring->next_to_use = first;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
	return NETDEV_TX_OK;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
 * e1000_tx_timeout - Respond to a Tx Hang
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
static void e1000_tx_timeout(struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
	/* Do the reset outside of interrupt context */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
	adapter->tx_timeout_count++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
	schedule_work(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
static void e1000_reset_task(struct work_struct *work)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
	struct e1000_adapter *adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
	adapter = container_of(work, struct e1000_adapter, reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
	/* don't run the task if already down */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
	if (test_bit(__E1000_DOWN, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
	if (!(adapter->flags & FLAG_RESTART_NOW)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
		e1000e_dump(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
		e_err("Reset adapter unexpectedly\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
	e1000e_reinit_locked(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
 * e1000_get_stats64 - Get System Network Statistics
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
 * @stats: rtnl_link_stats64 pointer
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
 * Returns the address of the device statistics structure.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
					     struct rtnl_link_stats64 *stats)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
	memset(stats, 0, sizeof(struct rtnl_link_stats64));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
	spin_lock(&adapter->stats64_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
	e1000e_update_stats(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
	/* Fill out the OS statistics structure */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
	stats->rx_bytes = adapter->stats.gorc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
	stats->rx_packets = adapter->stats.gprc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
	stats->tx_bytes = adapter->stats.gotc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
	stats->tx_packets = adapter->stats.gptc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
	stats->multicast = adapter->stats.mprc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
	stats->collisions = adapter->stats.colc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
	/* Rx Errors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	/* RLEC on some newer hardware can be incorrect so build
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	 * our own version based on RUC and ROC
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
	stats->rx_errors = adapter->stats.rxerrc +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
	    adapter->stats.crcerrs + adapter->stats.algnerrc +
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	    adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
	stats->rx_length_errors = adapter->stats.ruc + adapter->stats.roc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
	stats->rx_crc_errors = adapter->stats.crcerrs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
	stats->rx_frame_errors = adapter->stats.algnerrc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
	stats->rx_missed_errors = adapter->stats.mpc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
	/* Tx Errors */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
	stats->tx_errors = adapter->stats.ecol + adapter->stats.latecol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
	stats->tx_aborted_errors = adapter->stats.ecol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
	stats->tx_window_errors = adapter->stats.latecol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
	stats->tx_carrier_errors = adapter->stats.tncrs;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
	/* Tx Dropped needs to be maintained elsewhere */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
	spin_unlock(&adapter->stats64_lock);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
	return stats;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
 * e1000_change_mtu - Change the Maximum Transfer Unit
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
 * @new_mtu: new value for maximum frame size
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
 * Returns 0 on success, negative on failure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
	/* Jumbo frame support */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
		e_err("Jumbo Frames not supported.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
		return -EINVAL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
	/* Supported frame sizes */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
	    (max_frame > adapter->max_hw_frame_size)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
		e_err("Unsupported MTU setting\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
		return -EINVAL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
	/* Jumbo frame workaround on 82579 and newer requires CRC be stripped */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
	if ((adapter->hw.mac.type >= e1000_pch2lan) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
	    !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
	    (new_mtu > ETH_DATA_LEN)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
		e_err("Jumbo Frames not supported on this device when CRC stripping is disabled.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
		return -EINVAL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
		usleep_range(1000, 2000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
	adapter->max_frame_size = max_frame;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
	netdev->mtu = new_mtu;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
	if (netif_running(netdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
		e1000e_down(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
	 * means we reserve 2 more, this pushes us to allocate from the next
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
	 * larger slab size.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
	 * i.e. RXBUFFER_2048 --> size-4096 slab
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
	 * However with the new *_jumbo_rx* routines, jumbo receives will use
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
	 * fragmented skbs
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
	if (max_frame <= 2048)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
		adapter->rx_buffer_len = 2048;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
		adapter->rx_buffer_len = 4096;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
	/* adjust allocation if LPE protects us, and we aren't using SBP */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
	    (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
		    + ETH_FCS_LEN;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
	if (netif_running(netdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
		e1000e_up(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
		e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
	clear_bit(__E1000_RESETTING, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
			   int cmd)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
	struct mii_ioctl_data *data = if_mii(ifr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
	if (adapter->hw.phy.media_type != e1000_media_type_copper)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
		return -EOPNOTSUPP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
	switch (cmd) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
	case SIOCGMIIPHY:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
		data->phy_id = adapter->hw.phy.addr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
	case SIOCGMIIREG:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
		e1000_phy_read_status(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
		switch (data->reg_num & 0x1F) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
		case MII_BMCR:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
			data->val_out = adapter->phy_regs.bmcr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
		case MII_BMSR:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
			data->val_out = adapter->phy_regs.bmsr;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
		case MII_PHYSID1:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
			data->val_out = (adapter->hw.phy.id >> 16);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
		case MII_PHYSID2:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
			data->val_out = (adapter->hw.phy.id & 0xFFFF);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
		case MII_ADVERTISE:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
			data->val_out = adapter->phy_regs.advertise;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
		case MII_LPA:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
			data->val_out = adapter->phy_regs.lpa;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
		case MII_EXPANSION:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
			data->val_out = adapter->phy_regs.expansion;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
		case MII_CTRL1000:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
			data->val_out = adapter->phy_regs.ctrl1000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
		case MII_STAT1000:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
			data->val_out = adapter->phy_regs.stat1000;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
		case MII_ESTATUS:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
			data->val_out = adapter->phy_regs.estatus;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
		default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
			return -EIO;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
	case SIOCSMIIREG:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
		return -EOPNOTSUPP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
 * e1000e_hwtstamp_ioctl - control hardware time stamping
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
 * @ifreq: interface request
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
 * Outgoing time stamping can be enabled and disabled. Play nice and
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
 * disable it when requested, although it shouldn't cause any overhead
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
 * when no packet needs it. At most one packet in the queue may be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
 * marked for time stamping, otherwise it would be impossible to tell
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
 * for sure to which packet the hardware time stamp belongs.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
 * Incoming time stamping has to be configured via the hardware filters.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
 * Not all combinations are supported, in particular event type has to be
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
 * specified. Matching the kind of event packet is not supported, with the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
 * exception of "all V2 events regardless of level 2 or 4".
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
static int e1000e_hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
	struct hwtstamp_config config;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
	int ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
		return -EFAULT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
	adapter->hwtstamp_config = config;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
	ret_val = e1000e_config_hwtstamp(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
	if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
		return ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
	config = adapter->hwtstamp_config;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
	switch (config.rx_filter) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5821
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5822
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5823
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5824
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5825
		/* With V2 type filters which specify a Sync or Delay Request,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5826
		 * Path Delay Request/Response messages are also time stamped
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5827
		 * by hardware so notify the caller the requested packets plus
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5828
		 * some others are time stamped.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5829
		 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5830
		config.rx_filter = HWTSTAMP_FILTER_SOME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5831
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5832
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5833
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5834
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5835
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5836
	return copy_to_user(ifr->ifr_data, &config,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5837
			    sizeof(config)) ? -EFAULT : 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5838
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5839
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5840
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5841
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5842
	switch (cmd) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5843
	case SIOCGMIIPHY:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5844
	case SIOCGMIIREG:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5845
	case SIOCSMIIREG:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5846
		return e1000_mii_ioctl(netdev, ifr, cmd);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5847
	case SIOCSHWTSTAMP:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5848
		return e1000e_hwtstamp_ioctl(netdev, ifr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5849
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5850
		return -EOPNOTSUPP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5851
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5852
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5853
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5854
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5855
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5856
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5857
	u32 i, mac_reg;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5858
	u16 phy_reg, wuc_enable;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5859
	int retval;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5860
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5861
	/* copy MAC RARs to PHY RARs */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5862
	e1000_copy_rx_addrs_to_phy_ich8lan(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5863
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5864
	retval = hw->phy.ops.acquire(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5865
	if (retval) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5866
		e_err("Could not acquire PHY\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5867
		return retval;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5868
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5869
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5870
	/* Enable access to wakeup registers on and set page to BM_WUC_PAGE */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5871
	retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5872
	if (retval)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5873
		goto release;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5874
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5875
	/* copy MAC MTA to PHY MTA - only needed for pchlan */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5876
	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5877
		mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5878
		hw->phy.ops.write_reg_page(hw, BM_MTA(i),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5879
					   (u16)(mac_reg & 0xFFFF));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5880
		hw->phy.ops.write_reg_page(hw, BM_MTA(i) + 1,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5881
					   (u16)((mac_reg >> 16) & 0xFFFF));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5882
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5883
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5884
	/* configure PHY Rx Control register */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5885
	hw->phy.ops.read_reg_page(&adapter->hw, BM_RCTL, &phy_reg);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5886
	mac_reg = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5887
	if (mac_reg & E1000_RCTL_UPE)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5888
		phy_reg |= BM_RCTL_UPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5889
	if (mac_reg & E1000_RCTL_MPE)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5890
		phy_reg |= BM_RCTL_MPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5891
	phy_reg &= ~(BM_RCTL_MO_MASK);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5892
	if (mac_reg & E1000_RCTL_MO_3)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5893
		phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5894
			    << BM_RCTL_MO_SHIFT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5895
	if (mac_reg & E1000_RCTL_BAM)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5896
		phy_reg |= BM_RCTL_BAM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5897
	if (mac_reg & E1000_RCTL_PMCF)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5898
		phy_reg |= BM_RCTL_PMCF;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5899
	mac_reg = er32(CTRL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5900
	if (mac_reg & E1000_CTRL_RFCE)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5901
		phy_reg |= BM_RCTL_RFCE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5902
	hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5903
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5904
	/* enable PHY wakeup in MAC register */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5905
	ew32(WUFC, wufc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5906
	ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5907
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5908
	/* configure and enable PHY wakeup in PHY registers */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5909
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5910
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5911
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5912
	/* activate PHY wakeup */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5913
	wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5914
	retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5915
	if (retval)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5916
		e_err("Could not set PHY Host Wakeup bit\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5917
release:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5918
	hw->phy.ops.release(hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5919
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5920
	return retval;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5921
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5922
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5923
static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5924
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5925
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5926
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5927
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5928
	u32 ctrl, ctrl_ext, rctl, status;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5929
	/* Runtime suspend should only enable wakeup for link changes */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5930
	u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5931
	int retval = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5932
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5933
	netif_device_detach(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5934
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5935
	if (netif_running(netdev)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5936
		int count = E1000_CHECK_RESET_COUNT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5937
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5938
		while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5939
			usleep_range(10000, 20000);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5940
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5941
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5942
		e1000e_down(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5943
		e1000_free_irq(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5944
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5945
	e1000e_reset_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5946
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5947
	status = er32(STATUS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5948
	if (status & E1000_STATUS_LU)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5949
		wufc &= ~E1000_WUFC_LNKC;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5950
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5951
	if (wufc) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5952
		e1000_setup_rctl(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5953
		e1000e_set_rx_mode(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5954
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5955
		/* turn on all-multi mode if wake on multicast is enabled */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5956
		if (wufc & E1000_WUFC_MC) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5957
			rctl = er32(RCTL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5958
			rctl |= E1000_RCTL_MPE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5959
			ew32(RCTL, rctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5960
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5961
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5962
		ctrl = er32(CTRL);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5963
		ctrl |= E1000_CTRL_ADVD3WUC;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5964
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5965
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5966
		ew32(CTRL, ctrl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5967
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5968
		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5969
		    adapter->hw.phy.media_type ==
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5970
		    e1000_media_type_internal_serdes) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5971
			/* keep the laser running in D3 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5972
			ctrl_ext = er32(CTRL_EXT);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5973
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5974
			ew32(CTRL_EXT, ctrl_ext);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5975
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5976
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5977
		if (adapter->flags & FLAG_IS_ICH)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5978
			e1000_suspend_workarounds_ich8lan(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5979
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5980
		/* Allow time for pending master requests to run */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5981
		e1000e_disable_pcie_master(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5982
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5983
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5984
			/* enable wakeup by the PHY */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5985
			retval = e1000_init_phy_wakeup(adapter, wufc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5986
			if (retval)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5987
				return retval;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5988
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5989
			/* enable wakeup by the MAC */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5990
			ew32(WUFC, wufc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5991
			ew32(WUC, E1000_WUC_PME_EN);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5992
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5993
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5994
		ew32(WUC, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5995
		ew32(WUFC, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5996
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5997
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5998
	if (adapter->hw.phy.type == e1000_phy_igp_3)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5999
		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6000
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6001
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6002
	 * would have already happened in close and is redundant.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6003
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6004
	e1000e_release_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6005
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6006
	pci_clear_master(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6007
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6008
	/* The pci-e switch on some quad port adapters will report a
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6009
	 * correctable error when the MAC transitions from D0 to D3.  To
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6010
	 * prevent this we need to mask off the correctable errors on the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6011
	 * downstream port of the pci-e switch.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6012
	 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6013
	 * We don't have the associated upstream bridge while assigning
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6014
	 * the PCI device into guest. For example, the KVM on power is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6015
	 * one of the cases.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6016
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6017
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6018
		struct pci_dev *us_dev = pdev->bus->self;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6019
		u16 devctl;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6020
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6021
		if (!us_dev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6022
			return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6023
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6024
		pcie_capability_read_word(us_dev, PCI_EXP_DEVCTL, &devctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6025
		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6026
					   (devctl & ~PCI_EXP_DEVCTL_CERE));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6027
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6028
		pci_save_state(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6029
		pci_prepare_to_sleep(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6030
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6031
		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6032
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6033
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6034
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6035
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6036
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6037
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6038
 * e1000e_disable_aspm - Disable ASPM states
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6039
 * @pdev: pointer to PCI device struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6040
 * @state: bit-mask of ASPM states to disable
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6041
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6042
 * Some devices *must* have certain ASPM states disabled per hardware errata.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6043
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6044
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6045
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6046
	struct pci_dev *parent = pdev->bus->self;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6047
	u16 aspm_dis_mask = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6048
	u16 pdev_aspmc, parent_aspmc;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6049
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6050
	switch (state) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6051
	case PCIE_LINK_STATE_L0S:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6052
	case PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6053
		aspm_dis_mask |= PCI_EXP_LNKCTL_ASPM_L0S;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6054
		/* fall-through - can't have L1 without L0s */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6055
	case PCIE_LINK_STATE_L1:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6056
		aspm_dis_mask |= PCI_EXP_LNKCTL_ASPM_L1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6057
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6058
	default:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6059
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6060
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6061
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6062
	pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &pdev_aspmc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6063
	pdev_aspmc &= PCI_EXP_LNKCTL_ASPMC;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6064
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6065
	if (parent) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6066
		pcie_capability_read_word(parent, PCI_EXP_LNKCTL,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6067
					  &parent_aspmc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6068
		parent_aspmc &= PCI_EXP_LNKCTL_ASPMC;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6069
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6070
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6071
	/* Nothing to do if the ASPM states to be disabled already are */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6072
	if (!(pdev_aspmc & aspm_dis_mask) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6073
	    (!parent || !(parent_aspmc & aspm_dis_mask)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6074
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6075
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6076
	dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6077
		 (aspm_dis_mask & pdev_aspmc & PCI_EXP_LNKCTL_ASPM_L0S) ?
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6078
		 "L0s" : "",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6079
		 (aspm_dis_mask & pdev_aspmc & PCI_EXP_LNKCTL_ASPM_L1) ?
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6080
		 "L1" : "");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6081
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6082
#ifdef CONFIG_PCIEASPM
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6083
	pci_disable_link_state_locked(pdev, state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6084
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6085
	/* Double-check ASPM control.  If not disabled by the above, the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6086
	 * BIOS is preventing that from happening (or CONFIG_PCIEASPM is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6087
	 * not enabled); override by writing PCI config space directly.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6088
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6089
	pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &pdev_aspmc);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6090
	pdev_aspmc &= PCI_EXP_LNKCTL_ASPMC;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6091
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6092
	if (!(aspm_dis_mask & pdev_aspmc))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6093
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6094
#endif
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6095
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6096
	/* Both device and parent should have the same ASPM setting.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6097
	 * Disable ASPM in downstream component first and then upstream.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6098
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6099
	pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, aspm_dis_mask);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6100
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6101
	if (parent)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6102
		pcie_capability_clear_word(parent, PCI_EXP_LNKCTL,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6103
					   aspm_dis_mask);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6104
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6105
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6106
#ifdef CONFIG_PM
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6107
static bool e1000e_pm_ready(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6108
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6109
	return !!adapter->tx_ring->buffer_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6110
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6111
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6112
static int __e1000_resume(struct pci_dev *pdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6113
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6114
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6115
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6116
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6117
	u16 aspm_disable_flag = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6118
	u32 err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6119
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6120
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6121
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6122
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6123
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6124
	if (aspm_disable_flag)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6125
		e1000e_disable_aspm(pdev, aspm_disable_flag);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6126
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6127
	pci_set_master(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6128
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6129
	e1000e_set_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6130
	if (netif_running(netdev)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6131
		err = e1000_request_irq(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6132
		if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6133
			return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6134
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6135
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6136
	if (hw->mac.type >= e1000_pch2lan)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6137
		e1000_resume_workarounds_pchlan(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6138
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6139
	e1000e_power_up_phy(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6140
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6141
	/* report the system wakeup cause from S3/S4 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6142
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6143
		u16 phy_data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6144
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6145
		e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6146
		if (phy_data) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6147
			e_info("PHY Wakeup cause - %s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6148
			       phy_data & E1000_WUS_EX ? "Unicast Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6149
			       phy_data & E1000_WUS_MC ? "Multicast Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6150
			       phy_data & E1000_WUS_BC ? "Broadcast Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6151
			       phy_data & E1000_WUS_MAG ? "Magic Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6152
			       phy_data & E1000_WUS_LNKC ?
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6153
			       "Link Status Change" : "other");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6154
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6155
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6156
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6157
		u32 wus = er32(WUS);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6158
		if (wus) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6159
			e_info("MAC Wakeup cause - %s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6160
			       wus & E1000_WUS_EX ? "Unicast Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6161
			       wus & E1000_WUS_MC ? "Multicast Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6162
			       wus & E1000_WUS_BC ? "Broadcast Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6163
			       wus & E1000_WUS_MAG ? "Magic Packet" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6164
			       wus & E1000_WUS_LNKC ? "Link Status Change" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6165
			       "other");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6166
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6167
		ew32(WUS, ~0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6168
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6169
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6170
	e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6171
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6172
	e1000_init_manageability_pt(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6173
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6174
	if (netif_running(netdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6175
		e1000e_up(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6176
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6177
	netif_device_attach(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6178
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6179
	/* If the controller has AMT, do not set DRV_LOAD until the interface
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6180
	 * is up.  For all other cases, let the f/w know that the h/w is now
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6181
	 * under the control of the driver.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6182
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6183
	if (!(adapter->flags & FLAG_HAS_AMT))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6184
		e1000e_get_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6185
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6186
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6187
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6188
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6189
#ifdef CONFIG_PM_SLEEP
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6190
static int e1000_suspend(struct device *dev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6191
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6192
	struct pci_dev *pdev = to_pci_dev(dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6193
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6194
	return __e1000_shutdown(pdev, false);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6195
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6196
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6197
static int e1000_resume(struct device *dev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6198
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6199
	struct pci_dev *pdev = to_pci_dev(dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6200
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6201
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6202
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6203
	if (e1000e_pm_ready(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6204
		adapter->idle_check = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6205
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6206
	return __e1000_resume(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6207
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6208
#endif /* CONFIG_PM_SLEEP */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6209
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6210
#ifdef CONFIG_PM_RUNTIME
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6211
static int e1000_runtime_suspend(struct device *dev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6212
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6213
	struct pci_dev *pdev = to_pci_dev(dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6214
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6215
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6216
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6217
	if (!e1000e_pm_ready(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6218
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6219
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6220
	return __e1000_shutdown(pdev, true);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6221
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6222
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6223
static int e1000_idle(struct device *dev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6224
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6225
	struct pci_dev *pdev = to_pci_dev(dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6226
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6227
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6228
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6229
	if (!e1000e_pm_ready(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6230
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6231
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6232
	if (adapter->idle_check) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6233
		adapter->idle_check = false;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6234
		if (!e1000e_has_link(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6235
			pm_schedule_suspend(dev, MSEC_PER_SEC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6236
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6237
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6238
	return -EBUSY;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6239
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6240
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6241
static int e1000_runtime_resume(struct device *dev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6242
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6243
	struct pci_dev *pdev = to_pci_dev(dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6244
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6245
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6246
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6247
	if (!e1000e_pm_ready(adapter))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6248
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6249
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6250
	adapter->idle_check = !dev->power.runtime_auto;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6251
	return __e1000_resume(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6252
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6253
#endif /* CONFIG_PM_RUNTIME */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6254
#endif /* CONFIG_PM */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6255
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6256
static void e1000_shutdown(struct pci_dev *pdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6257
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6258
	__e1000_shutdown(pdev, false);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6259
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6260
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6261
#ifdef CONFIG_NET_POLL_CONTROLLER
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6262
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6263
static irqreturn_t e1000_intr_msix(int __always_unused irq, void *data)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6264
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6265
	struct net_device *netdev = data;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6266
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6267
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6268
	if (adapter->msix_entries) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6269
		int vector, msix_irq;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6270
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6271
		vector = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6272
		msix_irq = adapter->msix_entries[vector].vector;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6273
		disable_irq(msix_irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6274
		e1000_intr_msix_rx(msix_irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6275
		enable_irq(msix_irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6276
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6277
		vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6278
		msix_irq = adapter->msix_entries[vector].vector;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6279
		disable_irq(msix_irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6280
		e1000_intr_msix_tx(msix_irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6281
		enable_irq(msix_irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6282
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6283
		vector++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6284
		msix_irq = adapter->msix_entries[vector].vector;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6285
		disable_irq(msix_irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6286
		e1000_msix_other(msix_irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6287
		enable_irq(msix_irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6288
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6289
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6290
	return IRQ_HANDLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6291
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6292
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6293
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6294
 * e1000_netpoll
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6295
 * @netdev: network interface device structure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6296
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6297
 * Polling 'interrupt' - used by things like netconsole to send skbs
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6298
 * without having to re-enable interrupts. It's not called while
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6299
 * the interrupt routine is executing.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6300
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6301
static void e1000_netpoll(struct net_device *netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6302
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6303
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6304
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6305
	switch (adapter->int_mode) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6306
	case E1000E_INT_MODE_MSIX:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6307
		e1000_intr_msix(adapter->pdev->irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6308
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6309
	case E1000E_INT_MODE_MSI:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6310
		disable_irq(adapter->pdev->irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6311
		e1000_intr_msi(adapter->pdev->irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6312
		enable_irq(adapter->pdev->irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6313
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6314
	default:		/* E1000E_INT_MODE_LEGACY */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6315
		disable_irq(adapter->pdev->irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6316
		e1000_intr(adapter->pdev->irq, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6317
		enable_irq(adapter->pdev->irq);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6318
		break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6319
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6320
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6321
#endif
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6322
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6323
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6324
 * e1000_io_error_detected - called when PCI error is detected
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6325
 * @pdev: Pointer to PCI device
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6326
 * @state: The current pci connection state
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6327
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6328
 * This function is called after a PCI bus error affecting
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6329
 * this device has been detected.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6330
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6331
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6332
						pci_channel_state_t state)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6333
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6334
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6335
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6336
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6337
	netif_device_detach(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6338
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6339
	if (state == pci_channel_io_perm_failure)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6340
		return PCI_ERS_RESULT_DISCONNECT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6341
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6342
	if (netif_running(netdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6343
		e1000e_down(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6344
	pci_disable_device(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6345
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6346
	/* Request a slot slot reset. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6347
	return PCI_ERS_RESULT_NEED_RESET;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6348
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6349
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6350
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6351
 * e1000_io_slot_reset - called after the pci bus has been reset.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6352
 * @pdev: Pointer to PCI device
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6353
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6354
 * Restart the card from scratch, as if from a cold-boot. Implementation
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6355
 * resembles the first-half of the e1000_resume routine.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6356
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6357
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6358
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6359
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6360
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6361
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6362
	u16 aspm_disable_flag = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6363
	int err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6364
	pci_ers_result_t result;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6365
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6366
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6367
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6368
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6369
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6370
	if (aspm_disable_flag)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6371
		e1000e_disable_aspm(pdev, aspm_disable_flag);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6372
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6373
	err = pci_enable_device_mem(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6374
	if (err) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6375
		dev_err(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6376
			"Cannot re-enable PCI device after reset.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6377
		result = PCI_ERS_RESULT_DISCONNECT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6378
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6379
		pdev->state_saved = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6380
		pci_restore_state(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6381
		pci_set_master(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6382
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6383
		pci_enable_wake(pdev, PCI_D3hot, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6384
		pci_enable_wake(pdev, PCI_D3cold, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6385
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6386
		e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6387
		ew32(WUS, ~0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6388
		result = PCI_ERS_RESULT_RECOVERED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6389
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6390
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6391
	pci_cleanup_aer_uncorrect_error_status(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6392
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6393
	return result;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6394
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6395
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6396
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6397
 * e1000_io_resume - called when traffic can start flowing again.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6398
 * @pdev: Pointer to PCI device
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6399
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6400
 * This callback is called when the error recovery driver tells us that
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6401
 * its OK to resume normal operation. Implementation resembles the
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6402
 * second-half of the e1000_resume routine.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6403
 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6404
static void e1000_io_resume(struct pci_dev *pdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6405
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6406
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6407
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6408
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6409
	e1000_init_manageability_pt(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6410
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6411
	if (netif_running(netdev)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6412
		if (e1000e_up(adapter)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6413
			dev_err(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6414
				"can't bring device back up after reset\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6415
			return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6416
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6417
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6418
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6419
	netif_device_attach(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6420
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6421
	/* If the controller has AMT, do not set DRV_LOAD until the interface
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6422
	 * is up.  For all other cases, let the f/w know that the h/w is now
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6423
	 * under the control of the driver.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6424
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6425
	if (!(adapter->flags & FLAG_HAS_AMT))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6426
		e1000e_get_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6427
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6428
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6429
static void e1000_print_device_info(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6430
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6431
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6432
	struct net_device *netdev = adapter->netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6433
	u32 ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6434
	u8 pba_str[E1000_PBANUM_LENGTH];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6435
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6436
	/* print bus type/speed/width info */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6437
	e_info("(PCI Express:2.5GT/s:%s) %pM\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6438
	       /* bus width */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6439
	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6440
		"Width x1"),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6441
	       /* MAC address */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6442
	       netdev->dev_addr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6443
	e_info("Intel(R) PRO/%s Network Connection\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6444
	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6445
	ret_val = e1000_read_pba_string_generic(hw, pba_str,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6446
						E1000_PBANUM_LENGTH);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6447
	if (ret_val)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6448
		strlcpy((char *)pba_str, "Unknown", sizeof(pba_str));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6449
	e_info("MAC: %d, PHY: %d, PBA No: %s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6450
	       hw->mac.type, hw->phy.type, pba_str);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6451
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6452
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6453
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6454
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6455
	struct e1000_hw *hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6456
	int ret_val;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6457
	u16 buf = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6458
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6459
	if (hw->mac.type != e1000_82573)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6460
		return;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6461
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6462
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6463
	le16_to_cpus(&buf);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6464
	if (!ret_val && (!(buf & (1 << 0)))) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6465
		/* Deep Smart Power Down (DSPD) */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6466
		dev_warn(&adapter->pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6467
			 "Warning: detected DSPD enabled in EEPROM\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6468
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6469
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6470
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6471
static int e1000_set_features(struct net_device *netdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6472
			      netdev_features_t features)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6473
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6474
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6475
	netdev_features_t changed = features ^ netdev->features;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6476
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6477
	if (changed & (NETIF_F_TSO | NETIF_F_TSO6))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6478
		adapter->flags |= FLAG_TSO_FORCE;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6479
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6480
	if (!(changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6481
			 NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6482
			 NETIF_F_RXALL)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6483
		return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6484
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6485
	if (changed & NETIF_F_RXFCS) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6486
		if (features & NETIF_F_RXFCS) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6487
			adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6488
		} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6489
			/* We need to take it back to defaults, which might mean
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6490
			 * stripping is still disabled at the adapter level.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6491
			 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6492
			if (adapter->flags2 & FLAG2_DFLT_CRC_STRIPPING)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6493
				adapter->flags2 |= FLAG2_CRC_STRIPPING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6494
			else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6495
				adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6496
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6497
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6498
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6499
	netdev->features = features;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6500
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6501
	if (netif_running(netdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6502
		e1000e_reinit_locked(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6503
	else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6504
		e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6505
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6506
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6507
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6508
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6509
static const struct net_device_ops e1000e_netdev_ops = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6510
	.ndo_open		= e1000_open,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6511
	.ndo_stop		= e1000_close,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6512
	.ndo_start_xmit		= e1000_xmit_frame,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6513
	.ndo_get_stats64	= e1000e_get_stats64,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6514
	.ndo_set_rx_mode	= e1000e_set_rx_mode,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6515
	.ndo_set_mac_address	= e1000_set_mac,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6516
	.ndo_change_mtu		= e1000_change_mtu,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6517
	.ndo_do_ioctl		= e1000_ioctl,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6518
	.ndo_tx_timeout		= e1000_tx_timeout,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6519
	.ndo_validate_addr	= eth_validate_addr,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6520
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6521
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6522
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6523
#ifdef CONFIG_NET_POLL_CONTROLLER
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6524
	.ndo_poll_controller	= e1000_netpoll,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6525
#endif
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6526
	.ndo_set_features = e1000_set_features,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6527
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6528
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6529
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6530
 * e1000_probe - Device Initialization Routine
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6531
 * @pdev: PCI device information struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6532
 * @ent: entry in e1000_pci_tbl
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6533
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6534
 * Returns 0 on success, negative on failure
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6535
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6536
 * e1000_probe initializes an adapter identified by a pci_dev structure.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6537
 * The OS initialization, configuring of the adapter private structure,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6538
 * and a hardware reset occur.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6539
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6540
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6541
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6542
	struct net_device *netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6543
	struct e1000_adapter *adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6544
	struct e1000_hw *hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6545
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6546
	resource_size_t mmio_start, mmio_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6547
	resource_size_t flash_start, flash_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6548
	static int cards_found;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6549
	u16 aspm_disable_flag = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6550
	int bars, i, err, pci_using_dac;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6551
	u16 eeprom_data = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6552
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6553
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6554
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6555
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6556
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6557
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6558
	if (aspm_disable_flag)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6559
		e1000e_disable_aspm(pdev, aspm_disable_flag);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6560
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6561
	err = pci_enable_device_mem(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6562
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6563
		return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6564
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6565
	pci_using_dac = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6566
	err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6567
	if (!err) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6568
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6569
		if (!err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6570
			pci_using_dac = 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6571
	} else {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6572
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6573
		if (err) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6574
			err = dma_set_coherent_mask(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6575
						    DMA_BIT_MASK(32));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6576
			if (err) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6577
				dev_err(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6578
					"No usable DMA configuration, aborting\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6579
				goto err_dma;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6580
			}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6581
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6582
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6583
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6584
	bars = pci_select_bars(pdev, IORESOURCE_MEM);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6585
	err = pci_request_selected_regions_exclusive(pdev, bars,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6586
						     e1000e_driver_name);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6587
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6588
		goto err_pci_reg;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6589
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6590
	/* AER (Advanced Error Reporting) hooks */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6591
	pci_enable_pcie_error_reporting(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6592
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6593
	pci_set_master(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6594
	/* PCI config space info */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6595
	err = pci_save_state(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6596
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6597
		goto err_alloc_etherdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6598
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6599
	err = -ENOMEM;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6600
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6601
	if (!netdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6602
		goto err_alloc_etherdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6603
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6604
	SET_NETDEV_DEV(netdev, &pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6605
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6606
	netdev->irq = pdev->irq;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6607
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6608
	pci_set_drvdata(pdev, netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6609
	adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6610
	hw = &adapter->hw;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6611
	adapter->netdev = netdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6612
	adapter->pdev = pdev;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6613
	adapter->ei = ei;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6614
	adapter->pba = ei->pba;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6615
	adapter->flags = ei->flags;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6616
	adapter->flags2 = ei->flags2;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6617
	adapter->hw.adapter = adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6618
	adapter->hw.mac.type = ei->mac;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6619
	adapter->max_hw_frame_size = ei->max_hw_frame_size;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6620
	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6621
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6622
	mmio_start = pci_resource_start(pdev, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6623
	mmio_len = pci_resource_len(pdev, 0);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6624
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6625
	err = -EIO;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6626
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6627
	if (!adapter->hw.hw_addr)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6628
		goto err_ioremap;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6629
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6630
	if ((adapter->flags & FLAG_HAS_FLASH) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6631
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6632
		flash_start = pci_resource_start(pdev, 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6633
		flash_len = pci_resource_len(pdev, 1);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6634
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6635
		if (!adapter->hw.flash_address)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6636
			goto err_flashmap;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6637
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6638
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6639
	/* Set default EEE advertisement */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6640
	if (adapter->flags2 & FLAG2_HAS_EEE)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6641
		adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6642
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6643
	/* construct the net_device struct */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6644
	netdev->netdev_ops = &e1000e_netdev_ops;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6645
	e1000e_set_ethtool_ops(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6646
	netdev->watchdog_timeo = 5 * HZ;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6647
	netif_napi_add(netdev, &adapter->napi, e1000e_poll, 64);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6648
	strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6649
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6650
	netdev->mem_start = mmio_start;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6651
	netdev->mem_end = mmio_start + mmio_len;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6652
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6653
	adapter->bd_number = cards_found++;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6654
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6655
	e1000e_check_options(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6656
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6657
	/* setup adapter struct */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6658
	err = e1000_sw_init(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6659
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6660
		goto err_sw_init;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6661
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6662
	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6663
	memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6664
	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6665
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6666
	err = ei->get_variants(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6667
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6668
		goto err_hw_init;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6669
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6670
	if ((adapter->flags & FLAG_IS_ICH) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6671
	    (adapter->flags & FLAG_READ_ONLY_NVM))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6672
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6673
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6674
	hw->mac.ops.get_bus_info(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6675
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6676
	adapter->hw.phy.autoneg_wait_to_complete = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6677
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6678
	/* Copper options */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6679
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6680
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6681
		adapter->hw.phy.disable_polarity_correction = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6682
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6683
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6684
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6685
	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6686
		dev_info(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6687
			 "PHY reset is blocked due to SOL/IDER session.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6688
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6689
	/* Set initial default active device features */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6690
	netdev->features = (NETIF_F_SG |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6691
			    NETIF_F_HW_VLAN_CTAG_RX |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6692
			    NETIF_F_HW_VLAN_CTAG_TX |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6693
			    NETIF_F_TSO |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6694
			    NETIF_F_TSO6 |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6695
			    NETIF_F_RXHASH |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6696
			    NETIF_F_RXCSUM |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6697
			    NETIF_F_HW_CSUM);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6698
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6699
	/* Set user-changeable features (subset of all device features) */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6700
	netdev->hw_features = netdev->features;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6701
	netdev->hw_features |= NETIF_F_RXFCS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6702
	netdev->priv_flags |= IFF_SUPP_NOFCS;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6703
	netdev->hw_features |= NETIF_F_RXALL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6704
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6705
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6706
		netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6707
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6708
	netdev->vlan_features |= (NETIF_F_SG |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6709
				  NETIF_F_TSO |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6710
				  NETIF_F_TSO6 |
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6711
				  NETIF_F_HW_CSUM);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6712
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6713
	netdev->priv_flags |= IFF_UNICAST_FLT;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6714
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6715
	if (pci_using_dac) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6716
		netdev->features |= NETIF_F_HIGHDMA;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6717
		netdev->vlan_features |= NETIF_F_HIGHDMA;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6718
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6719
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6720
	if (e1000e_enable_mng_pass_thru(&adapter->hw))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6721
		adapter->flags |= FLAG_MNG_PT_ENABLED;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6722
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6723
	/* before reading the NVM, reset the controller to
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6724
	 * put the device in a known good starting state
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6725
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6726
	adapter->hw.mac.ops.reset_hw(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6727
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6728
	/* systems with ASPM and others may see the checksum fail on the first
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6729
	 * attempt. Let's give it a few tries
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6730
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6731
	for (i = 0;; i++) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6732
		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6733
			break;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6734
		if (i == 2) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6735
			dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6736
			err = -EIO;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6737
			goto err_eeprom;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6738
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6739
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6740
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6741
	e1000_eeprom_checks(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6742
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6743
	/* copy the MAC address */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6744
	if (e1000e_read_mac_addr(&adapter->hw))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6745
		dev_err(&pdev->dev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6746
			"NVM Read Error while reading MAC address\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6747
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6748
	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6749
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6750
	if (!is_valid_ether_addr(netdev->dev_addr)) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6751
		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6752
			netdev->dev_addr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6753
		err = -EIO;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6754
		goto err_eeprom;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6755
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6756
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6757
	init_timer(&adapter->watchdog_timer);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6758
	adapter->watchdog_timer.function = e1000_watchdog;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6759
	adapter->watchdog_timer.data = (unsigned long)adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6760
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6761
	init_timer(&adapter->phy_info_timer);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6762
	adapter->phy_info_timer.function = e1000_update_phy_info;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6763
	adapter->phy_info_timer.data = (unsigned long)adapter;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6764
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6765
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6766
	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6767
	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6768
	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6769
	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6770
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6771
	/* Initialize link parameters. User can change them with ethtool */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6772
	adapter->hw.mac.autoneg = 1;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6773
	adapter->fc_autoneg = true;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6774
	adapter->hw.fc.requested_mode = e1000_fc_default;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6775
	adapter->hw.fc.current_mode = e1000_fc_default;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6776
	adapter->hw.phy.autoneg_advertised = 0x2f;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6777
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6778
	/* Initial Wake on LAN setting - If APM wake is enabled in
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6779
	 * the EEPROM, enable the ACPI Magic Packet filter
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6780
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6781
	if (adapter->flags & FLAG_APME_IN_WUC) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6782
		/* APME bit in EEPROM is mapped to WUC.APME */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6783
		eeprom_data = er32(WUC);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6784
		eeprom_apme_mask = E1000_WUC_APME;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6785
		if ((hw->mac.type > e1000_ich10lan) &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6786
		    (eeprom_data & E1000_WUC_PHY_WAKE))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6787
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6788
	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6789
		if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6790
		    (adapter->hw.bus.func == 1))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6791
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_B,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6792
				       1, &eeprom_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6793
		else
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6794
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_A,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6795
				       1, &eeprom_data);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6796
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6797
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6798
	/* fetch WoL from EEPROM */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6799
	if (eeprom_data & eeprom_apme_mask)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6800
		adapter->eeprom_wol |= E1000_WUFC_MAG;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6801
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6802
	/* now that we have the eeprom settings, apply the special cases
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6803
	 * where the eeprom may be wrong or the board simply won't support
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6804
	 * wake on lan on a particular port
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6805
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6806
	if (!(adapter->flags & FLAG_HAS_WOL))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6807
		adapter->eeprom_wol = 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6808
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6809
	/* initialize the wol settings based on the eeprom settings */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6810
	adapter->wol = adapter->eeprom_wol;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6811
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6812
	/* make sure adapter isn't asleep if manageability is enabled */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6813
	if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) ||
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6814
	    (hw->mac.ops.check_mng_mode(hw)))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6815
		device_wakeup_enable(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6816
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6817
	/* save off EEPROM version number */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6818
	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6819
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6820
	/* reset the hardware with the new settings */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6821
	e1000e_reset(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6822
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6823
	/* If the controller has AMT, do not set DRV_LOAD until the interface
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6824
	 * is up.  For all other cases, let the f/w know that the h/w is now
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6825
	 * under the control of the driver.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6826
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6827
	if (!(adapter->flags & FLAG_HAS_AMT))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6828
		e1000e_get_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6829
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6830
	strlcpy(netdev->name, "eth%d", sizeof(netdev->name));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6831
	err = register_netdev(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6832
	if (err)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6833
		goto err_register;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6834
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6835
	/* carrier off reporting is important to ethtool even BEFORE open */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6836
	netif_carrier_off(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6837
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6838
	/* init PTP hardware clock */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6839
	e1000e_ptp_init(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6840
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6841
	e1000_print_device_info(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6842
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6843
	if (pci_dev_run_wake(pdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6844
		pm_runtime_put_noidle(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6845
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6846
	return 0;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6847
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6848
err_register:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6849
	if (!(adapter->flags & FLAG_HAS_AMT))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6850
		e1000e_release_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6851
err_eeprom:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6852
	if (hw->phy.ops.check_reset_block && !hw->phy.ops.check_reset_block(hw))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6853
		e1000_phy_hw_reset(&adapter->hw);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6854
err_hw_init:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6855
	kfree(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6856
	kfree(adapter->rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6857
err_sw_init:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6858
	if (adapter->hw.flash_address)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6859
		iounmap(adapter->hw.flash_address);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6860
	e1000e_reset_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6861
err_flashmap:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6862
	iounmap(adapter->hw.hw_addr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6863
err_ioremap:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6864
	free_netdev(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6865
err_alloc_etherdev:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6866
	pci_release_selected_regions(pdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6867
				     pci_select_bars(pdev, IORESOURCE_MEM));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6868
err_pci_reg:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6869
err_dma:
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6870
	pci_disable_device(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6871
	return err;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6872
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6873
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6874
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6875
 * e1000_remove - Device Removal Routine
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6876
 * @pdev: PCI device information struct
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6877
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6878
 * e1000_remove is called by the PCI subsystem to alert the driver
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6879
 * that it should release a PCI device.  The could be caused by a
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6880
 * Hot-Plug event, or because the driver is going to be removed from
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6881
 * memory.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6882
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6883
static void e1000_remove(struct pci_dev *pdev)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6884
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6885
	struct net_device *netdev = pci_get_drvdata(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6886
	struct e1000_adapter *adapter = netdev_priv(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6887
	bool down = test_bit(__E1000_DOWN, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6888
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6889
	e1000e_ptp_remove(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6890
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6891
	/* The timers may be rescheduled, so explicitly disable them
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6892
	 * from being rescheduled.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6893
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6894
	if (!down)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6895
		set_bit(__E1000_DOWN, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6896
	del_timer_sync(&adapter->watchdog_timer);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6897
	del_timer_sync(&adapter->phy_info_timer);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6898
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6899
	cancel_work_sync(&adapter->reset_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6900
	cancel_work_sync(&adapter->watchdog_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6901
	cancel_work_sync(&adapter->downshift_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6902
	cancel_work_sync(&adapter->update_phy_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6903
	cancel_work_sync(&adapter->print_hang_task);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6904
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6905
	if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6906
		cancel_work_sync(&adapter->tx_hwtstamp_work);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6907
		if (adapter->tx_hwtstamp_skb) {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6908
			dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6909
			adapter->tx_hwtstamp_skb = NULL;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6910
		}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6911
	}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6912
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6913
	if (!(netdev->flags & IFF_UP))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6914
		e1000_power_down_phy(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6915
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6916
	/* Don't lie to e1000_close() down the road. */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6917
	if (!down)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6918
		clear_bit(__E1000_DOWN, &adapter->state);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6919
	unregister_netdev(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6920
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6921
	if (pci_dev_run_wake(pdev))
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6922
		pm_runtime_get_noresume(&pdev->dev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6923
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6924
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6925
	 * would have already happened in close and is redundant.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6926
	 */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6927
	e1000e_release_hw_control(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6928
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6929
	e1000e_reset_interrupt_capability(adapter);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6930
	kfree(adapter->tx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6931
	kfree(adapter->rx_ring);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6932
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6933
	iounmap(adapter->hw.hw_addr);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6934
	if (adapter->hw.flash_address)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6935
		iounmap(adapter->hw.flash_address);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6936
	pci_release_selected_regions(pdev,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6937
				     pci_select_bars(pdev, IORESOURCE_MEM));
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6938
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6939
	free_netdev(netdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6940
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6941
	/* AER disable */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6942
	pci_disable_pcie_error_reporting(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6943
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6944
	pci_disable_device(pdev);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6945
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6946
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6947
/* PCI Error Recovery (ERS) */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6948
static const struct pci_error_handlers e1000_err_handler = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6949
	.error_detected = e1000_io_error_detected,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6950
	.slot_reset = e1000_io_slot_reset,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6951
	.resume = e1000_io_resume,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6952
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6953
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6954
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6955
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6956
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6957
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6958
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6959
	  board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6960
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6961
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6962
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6963
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6964
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6965
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6966
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6967
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6968
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6969
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6970
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6971
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6972
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6973
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6974
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6975
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6976
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6977
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6978
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6979
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6980
	  board_80003es2lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6981
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6982
	  board_80003es2lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6983
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6984
	  board_80003es2lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6985
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6986
	  board_80003es2lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6987
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6988
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6989
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6990
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6991
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6992
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6993
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6994
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6995
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6996
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6997
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6998
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6999
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7000
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7001
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7002
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7003
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7004
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7005
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7006
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7007
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7008
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7009
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7010
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7011
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7012
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7013
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_V), board_ich10lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7014
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7015
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7016
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7017
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7018
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7019
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7020
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7021
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7022
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7023
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_LM), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7024
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_V), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7025
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_LM), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7026
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_V), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7027
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_LM2), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7028
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_V2), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7029
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_LM3), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7030
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_V3), board_pch_lpt },
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7031
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7032
	{ 0, 0, 0, 0, 0, 0, 0 }	/* terminate list */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7033
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7034
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7035
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7036
#ifdef CONFIG_PM
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7037
static const struct dev_pm_ops e1000_pm_ops = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7038
	SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7039
	SET_RUNTIME_PM_OPS(e1000_runtime_suspend, e1000_runtime_resume,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7040
			   e1000_idle)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7041
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7042
#endif
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7043
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7044
/* PCI Device API Driver */
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7045
static struct pci_driver e1000_driver = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7046
	.name     = e1000e_driver_name,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7047
	.id_table = e1000_pci_tbl,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7048
	.probe    = e1000_probe,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7049
	.remove   = e1000_remove,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7050
#ifdef CONFIG_PM
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7051
	.driver   = {
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7052
		.pm = &e1000_pm_ops,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7053
	},
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7054
#endif
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7055
	.shutdown = e1000_shutdown,
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7056
	.err_handler = &e1000_err_handler
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7057
};
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7058
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7059
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7060
 * e1000_init_module - Driver Registration Routine
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7061
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7062
 * e1000_init_module is the first routine called when the driver is
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7063
 * loaded. All it does is register with the PCI subsystem.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7064
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7065
static int __init e1000_init_module(void)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7066
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7067
	int ret;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7068
	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7069
		e1000e_driver_version);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7070
	pr_info("Copyright(c) 1999 - 2013 Intel Corporation.\n");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7071
	ret = pci_register_driver(&e1000_driver);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7072
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7073
	return ret;
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7074
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7075
module_init(e1000_init_module);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7076
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7077
/**
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7078
 * e1000_exit_module - Driver Exit Cleanup Routine
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7079
 *
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7080
 * e1000_exit_module is called just before the driver is removed
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7081
 * from memory.
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7082
 **/
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7083
static void __exit e1000_exit_module(void)
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7084
{
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7085
	pci_unregister_driver(&e1000_driver);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7086
}
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7087
module_exit(e1000_exit_module);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7088
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7089
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7090
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7091
MODULE_LICENSE("GPL");
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7092
MODULE_VERSION(DRV_VERSION);
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7093
5b89b4e38cdc Added all drivers for kernel 3.12.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7094
/* netdev.c */