devices/e1000e/netdev-3.4-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2491 5e9221a78855
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.
2491
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2012 Intel Corporation.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/module.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/types.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/init.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/pci.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/vmalloc.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/pagemap.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/delay.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/netdevice.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <linux/interrupt.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <linux/tcp.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <linux/ipv6.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <linux/slab.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <net/checksum.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <net/ip6_checksum.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <linux/mii.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
#include <linux/ethtool.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include <linux/if_vlan.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
#include <linux/cpu.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#include <linux/smp.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
#include <linux/pm_qos.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#include <linux/pm_runtime.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
#include <linux/aer.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
#include <linux/prefetch.h>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
#include "e1000.h"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
#define DRV_EXTRAVERSION "-k"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
#define DRV_VERSION "1.9.5" DRV_EXTRAVERSION
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
char e1000e_driver_name[] = "e1000e";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
const char e1000e_driver_version[] = DRV_VERSION;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
static int debug = -1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
module_param(debug, int, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
static const struct e1000_info *e1000_info_tbl[] = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	[board_82571]		= &e1000_82571_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	[board_82572]		= &e1000_82572_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	[board_82573]		= &e1000_82573_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	[board_82574]		= &e1000_82574_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	[board_82583]		= &e1000_82583_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	[board_80003es2lan]	= &e1000_es2_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	[board_ich8lan]		= &e1000_ich8_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	[board_ich9lan]		= &e1000_ich9_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	[board_ich10lan]	= &e1000_ich10_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	[board_pchlan]		= &e1000_pch_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	[board_pch2lan]		= &e1000_pch2_info,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
struct e1000_reg_info {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	u32 ofs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	char *name;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
#define E1000_RDFH	0x02410	/* Rx Data FIFO Head - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
#define E1000_RDFT	0x02418	/* Rx Data FIFO Tail - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
#define E1000_RDFHS	0x02420	/* Rx Data FIFO Head Saved - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
#define E1000_RDFTS	0x02428	/* Rx Data FIFO Tail Saved - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
#define E1000_RDFPC	0x02430	/* Rx Data FIFO Packet Count - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
#define E1000_TDFH	0x03410	/* Tx Data FIFO Head - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
#define E1000_TDFT	0x03418	/* Tx Data FIFO Tail - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
#define E1000_TDFHS	0x03420	/* Tx Data FIFO Head Saved - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
#define E1000_TDFTS	0x03428	/* Tx Data FIFO Tail Saved - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
#define E1000_TDFPC	0x03430	/* Tx Data FIFO Packet Count - RW */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
static const struct e1000_reg_info e1000_reg_info_tbl[] = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	/* General Registers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	{E1000_CTRL, "CTRL"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	{E1000_STATUS, "STATUS"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	{E1000_CTRL_EXT, "CTRL_EXT"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	/* Interrupt Registers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	{E1000_ICR, "ICR"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	/* Rx Registers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	{E1000_RCTL, "RCTL"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	{E1000_RDLEN, "RDLEN"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	{E1000_RDH, "RDH"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	{E1000_RDT, "RDT"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	{E1000_RDTR, "RDTR"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	{E1000_RXDCTL(0), "RXDCTL"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	{E1000_ERT, "ERT"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	{E1000_RDBAL, "RDBAL"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	{E1000_RDBAH, "RDBAH"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	{E1000_RDFH, "RDFH"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	{E1000_RDFT, "RDFT"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	{E1000_RDFHS, "RDFHS"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	{E1000_RDFTS, "RDFTS"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	{E1000_RDFPC, "RDFPC"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	/* Tx Registers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
	{E1000_TCTL, "TCTL"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	{E1000_TDBAL, "TDBAL"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	{E1000_TDBAH, "TDBAH"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	{E1000_TDLEN, "TDLEN"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	{E1000_TDH, "TDH"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
	{E1000_TDT, "TDT"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
	{E1000_TIDV, "TIDV"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
	{E1000_TXDCTL(0), "TXDCTL"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
	{E1000_TADV, "TADV"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
	{E1000_TARC(0), "TARC"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
	{E1000_TDFH, "TDFH"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
	{E1000_TDFT, "TDFT"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	{E1000_TDFHS, "TDFHS"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	{E1000_TDFTS, "TDFTS"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	{E1000_TDFPC, "TDFPC"},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
	/* List Terminator */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	{0, NULL}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 * e1000_regdump - register printout routine
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	int n = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
	char rname[16];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	u32 regs[8];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	switch (reginfo->ofs) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	case E1000_RXDCTL(0):
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
		for (n = 0; n < 2; n++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
			regs[n] = __er32(hw, E1000_RXDCTL(n));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
	case E1000_TXDCTL(0):
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
		for (n = 0; n < 2; n++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
			regs[n] = __er32(hw, E1000_TXDCTL(n));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
	case E1000_TARC(0):
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
		for (n = 0; n < 2; n++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
			regs[n] = __er32(hw, E1000_TARC(n));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		pr_info("%-15s %08x\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
			reginfo->name, __er32(hw, reginfo->ofs));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
	pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
 * e1000e_dump - Print registers, Tx-ring and Rx-ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
static void e1000e_dump(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	struct e1000_reg_info *reginfo;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	struct e1000_ring *tx_ring = adapter->tx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	struct e1000_tx_desc *tx_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	struct my_u0 {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		__le64 a;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
		__le64 b;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	} *u0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
	struct e1000_ring *rx_ring = adapter->rx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	union e1000_rx_desc_packet_split *rx_desc_ps;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	union e1000_rx_desc_extended *rx_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	struct my_u1 {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		__le64 a;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		__le64 b;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		__le64 c;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		__le64 d;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	} *u1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	u32 staterr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	int i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	if (!netif_msg_hw(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	/* Print netdevice Info */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	if (netdev) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
		dev_info(&adapter->pdev->dev, "Net device Info\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
		pr_info("Device Name     state            trans_start      last_rx\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
		pr_info("%-15s %016lX %016lX %016lX\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
			netdev->name, netdev->state, netdev->trans_start,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
			netdev->last_rx);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	/* Print Registers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	dev_info(&adapter->pdev->dev, "Register Dump\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	pr_info(" Register Name   Value\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	     reginfo->name; reginfo++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
		e1000_regdump(hw, reginfo);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	/* Print Tx Ring Summary */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	if (!netdev || !netif_running(netdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	dev_info(&adapter->pdev->dev, "Tx Ring Summary\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
		0, tx_ring->next_to_use, tx_ring->next_to_clean,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
		(unsigned long long)buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
		buffer_info->length,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		buffer_info->next_to_watch,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
		(unsigned long long)buffer_info->time_stamp);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	/* Print Tx Ring */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	if (!netif_msg_tx_done(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
		goto rx_ring_summary;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	dev_info(&adapter->pdev->dev, "Tx Ring Dump\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	 * Legacy Transmit Descriptor
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	 *   +--------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	 *   +--------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	 *   +--------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	 *   63       48 47        36 35    32 31     24 23    16 15        0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	 *   63      48 47    40 39       32 31             16 15    8 7      0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	 *   +----------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	 *   +----------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	 *   +----------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	 * Extended Data Descriptor (DTYP=0x1)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	 *   +----------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	 * 0 |                     Buffer Address [63:0]                      |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	 *   +----------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	 *   +----------------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	pr_info("Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Legacy format\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Context format\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Data format\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		const char *next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		tx_desc = E1000_TX_DESC(*tx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
		u0 = (struct my_u0 *)tx_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
			next_desc = " NTC/U";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		else if (i == tx_ring->next_to_use)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
			next_desc = " NTU";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		else if (i == tx_ring->next_to_clean)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
			next_desc = " NTC";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
		else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
			next_desc = "";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p%s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
			(!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
			 ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
			i,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
			(unsigned long long)le64_to_cpu(u0->a),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
			(unsigned long long)le64_to_cpu(u0->b),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
			(unsigned long long)buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
			buffer_info->length, buffer_info->next_to_watch,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
			(unsigned long long)buffer_info->time_stamp,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
			buffer_info->skb, next_desc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
		if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
				       16, 1, phys_to_virt(buffer_info->dma),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
				       buffer_info->length, true);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	/* Print Rx Ring Summary */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
rx_ring_summary:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
	dev_info(&adapter->pdev->dev, "Rx Ring Summary\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	pr_info("Queue [NTU] [NTC]\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	pr_info(" %5d %5X %5X\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		0, rx_ring->next_to_use, rx_ring->next_to_clean);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	/* Print Rx Ring */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	if (!netif_msg_rx_status(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	dev_info(&adapter->pdev->dev, "Rx Ring Dump\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
	switch (adapter->rx_ps_pages) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	case 1:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	case 2:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	case 3:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		/* [Extended] Packet Split Receive Descriptor Format
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
		 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		 *    +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		 *  0 |                Buffer Address 0 [63:0]              |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
		 *    +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		 *  8 |                Buffer Address 1 [63:0]              |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		 *    +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
		 * 16 |                Buffer Address 2 [63:0]              |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		 *    +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		 * 24 |                Buffer Address 3 [63:0]              |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		 *    +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
		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");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		/* [Extended] Receive Descriptor (Write-Back) Format
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		 *   63       48 47    32 31     13 12    8 7    4 3        0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		 *   +------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		 * 0 | Packet   | IP     |  Rsvd   | MRQ   | Rsvd | MRQ RSS |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		 *   | Checksum | Ident  |         | Queue |      |  Type   |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		 *   +------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		 *   +------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		 *   63       48 47    32 31            20 19               0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		pr_info("RWB[desc]      [ck ipid mrqhsh] [vl   l0 ee  es] [ l3  l2  l1 hs] [reserved      ] ---------------- [bi->skb] <-- Ext Rx Write-Back format\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
		for (i = 0; i < rx_ring->count; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
			const char *next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
			buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
			rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
			u1 = (struct my_u1 *)rx_desc_ps;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
			staterr =
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
			    le32_to_cpu(rx_desc_ps->wb.middle.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
			if (i == rx_ring->next_to_use)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
				next_desc = " NTU";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
			else if (i == rx_ring->next_to_clean)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
				next_desc = " NTC";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
				next_desc = "";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
			if (staterr & E1000_RXD_STAT_DD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
				/* Descriptor Done */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX ---------------- %p%s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
					"RWB", i,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
					(unsigned long long)le64_to_cpu(u1->a),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
					(unsigned long long)le64_to_cpu(u1->b),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
					(unsigned long long)le64_to_cpu(u1->c),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
					(unsigned long long)le64_to_cpu(u1->d),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
					buffer_info->skb, next_desc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
			} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX %016llX %p%s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
					"R  ", i,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
					(unsigned long long)le64_to_cpu(u1->a),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
					(unsigned long long)le64_to_cpu(u1->b),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
					(unsigned long long)le64_to_cpu(u1->c),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
					(unsigned long long)le64_to_cpu(u1->d),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
					(unsigned long long)buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
					buffer_info->skb, next_desc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
				if (netif_msg_pktdata(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
					print_hex_dump(KERN_INFO, "",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
						DUMP_PREFIX_ADDRESS, 16, 1,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
						phys_to_virt(buffer_info->dma),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
						adapter->rx_ps_bsize0, true);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	case 0:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		/* Extended Receive Descriptor (Read) Format
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
		 *   +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		 * 0 |                Buffer Address [63:0]                |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		 *   +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		 * 8 |                      Reserved                       |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		 *   +-----------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
		pr_info("R  [desc]      [buf addr 63:0 ] [reserved 63:0 ] [bi->dma       ] [bi->skb] <-- Ext (Read) format\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
		/* Extended Receive Descriptor (Write-Back) Format
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
		 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		 *   63       48 47    32 31    24 23            4 3        0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
		 *   +------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
		 *   |     RSS Hash      |        |               |         |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
		 * 0 +-------------------+  Rsvd  |   Reserved    | MRQ RSS |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
		 *   | Packet   | IP     |        |               |  Type   |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		 *   | Checksum | Ident  |        |               |         |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
		 *   +------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
		 *   +------------------------------------------------------+
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
		 *   63       48 47    32 31            20 19               0
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
		pr_info("RWB[desc]      [cs ipid    mrq] [vt   ln xe  xs] [bi->skb] <-- Ext (Write-Back) format\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
		for (i = 0; i < rx_ring->count; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
			const char *next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
			buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
			rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
			u1 = (struct my_u1 *)rx_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
			if (i == rx_ring->next_to_use)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
				next_desc = " NTU";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
			else if (i == rx_ring->next_to_clean)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
				next_desc = " NTC";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
				next_desc = "";
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
			if (staterr & E1000_RXD_STAT_DD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
				/* Descriptor Done */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
				pr_info("%s[0x%03X]     %016llX %016llX ---------------- %p%s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
					"RWB", i,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
					(unsigned long long)le64_to_cpu(u1->a),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
					(unsigned long long)le64_to_cpu(u1->b),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
					buffer_info->skb, next_desc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
			} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %p%s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
					"R  ", i,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
					(unsigned long long)le64_to_cpu(u1->a),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
					(unsigned long long)le64_to_cpu(u1->b),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
					(unsigned long long)buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
					buffer_info->skb, next_desc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
				if (netif_msg_pktdata(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
					print_hex_dump(KERN_INFO, "",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
						       DUMP_PREFIX_ADDRESS, 16,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
						       1,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
						       phys_to_virt
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
						       (buffer_info->dma),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
						       adapter->rx_buffer_len,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
						       true);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
 * e1000_desc_unused - calculate if we have unused descriptors
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
static int e1000_desc_unused(struct e1000_ring *ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	if (ring->next_to_clean > ring->next_to_use)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		return ring->next_to_clean - ring->next_to_use - 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
 * e1000_receive_skb - helper function to handle Rx indications
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
 * @status: descriptor status field as written by hardware
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
 * @skb: pointer to sk_buff to be indicated to stack
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
static void e1000_receive_skb(struct e1000_adapter *adapter,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
			      struct net_device *netdev, struct sk_buff *skb,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
			      u8 status, __le16 vlan)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	u16 tag = le16_to_cpu(vlan);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	skb->protocol = eth_type_trans(skb, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	if (status & E1000_RXD_STAT_VP)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
		__vlan_hwaccel_put_tag(skb, tag);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	napi_gro_receive(&adapter->napi, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
 * e1000_rx_checksum - Receive Checksum Offload
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
 * @status_err: receive descriptor status and error fields
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
 * @csum: receive descriptor csum field
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
 * @sk_buff: socket buffer with received data
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
			      struct sk_buff *skb)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
	u16 status = (u16)status_err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
	u8 errors = (u8)(status_err >> 24);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	skb_checksum_none_assert(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	/* Rx checksum disabled */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	if (!(adapter->netdev->features & NETIF_F_RXCSUM))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	/* Ignore Checksum bit is set */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	if (status & E1000_RXD_STAT_IXSM)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	/* TCP/UDP checksum error bit or IP checksum error bit is set */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		/* let the stack verify checksum errors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
		adapter->hw_csum_err++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	/* TCP/UDP Checksum has not been calculated */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	/* It must be a TCP or UDP packet with a valid checksum */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	skb->ip_summed = CHECKSUM_UNNECESSARY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	adapter->hw_csum_good++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
 * e1000e_update_tail_wa - helper function for e1000e_update_[rt]dt_wa()
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
 * @hw: pointer to the HW structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
 * @tail: address of tail descriptor register
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
 * @i: value to write to tail descriptor register
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
 * When updating the tail register, the ME could be accessing Host CSR
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
 * registers at the same time.  Normally, this is handled in h/w by an
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
 * arbiter but on some parts there is a bug that acknowledges Host accesses
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
 * later than it should which could result in the descriptor register to
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
 * have an incorrect value.  Workaround this by checking the FWSM register
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 * which has bit 24 set while ME is accessing Host CSR registers, wait
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 * if it is set and try again a number of times.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, void __iomem *tail,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
					unsigned int i)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	unsigned int j = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	while ((j++ < E1000_ICH_FWSM_PCIM2PCI_COUNT) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	       (er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
		udelay(50);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	writel(i, tail);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	if ((j == E1000_ICH_FWSM_PCIM2PCI_COUNT) && (i != readl(tail)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
		return E1000_ERR_SWFW_SYNC;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	if (e1000e_update_tail_wa(hw, rx_ring->tail, i)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
		u32 rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		e_err("ME firmware caused invalid RDT - resetting\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		schedule_work(&adapter->reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	if (e1000e_update_tail_wa(hw, tx_ring->tail, i)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
		u32 tctl = er32(TCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
		ew32(TCTL, tctl & ~E1000_TCTL_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		e_err("ME firmware caused invalid TDT - resetting\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
		schedule_work(&adapter->reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
 * e1000_alloc_rx_buffers - Replace used receive buffers
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
				   int cleaned_count, gfp_t gfp)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	union e1000_rx_desc_extended *rx_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	struct sk_buff *skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	unsigned int bufsz = adapter->rx_buffer_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	i = rx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	while (cleaned_count--) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		skb = buffer_info->skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
		if (skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
			skb_trim(skb, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
			goto map_skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		if (!skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
			/* Better luck next round */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
			adapter->alloc_rx_buff_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
map_skb:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
						  adapter->rx_buffer_len,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
						  DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
			dev_err(&pdev->dev, "Rx DMA map failed\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
			adapter->rx_dma_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
			 * Force memory writes to complete before letting h/w
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
			 * know there are new descriptors to fetch.  (Only
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
			 * applicable for weak-ordered memory model archs,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
			 * such as IA-64).
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
			wmb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
				e1000e_update_rdt_wa(rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
				writel(i, rx_ring->tail);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		if (i == rx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
			i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	rx_ring->next_to_use = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
				      int cleaned_count, gfp_t gfp)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	union e1000_rx_desc_packet_split *rx_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	struct e1000_ps_page *ps_page;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	struct sk_buff *skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	unsigned int i, j;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
	i = rx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	while (cleaned_count--) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
			ps_page = &buffer_info->ps_pages[j];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
			if (j >= adapter->rx_ps_pages) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
				/* all unused desc entries get hw null ptr */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
				rx_desc->read.buffer_addr[j + 1] =
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
				    ~cpu_to_le64(0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
				continue;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
			if (!ps_page->page) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
				ps_page->page = alloc_page(gfp);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
				if (!ps_page->page) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
					adapter->alloc_rx_buff_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
					goto no_buffers;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
				}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
				ps_page->dma = dma_map_page(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
							    ps_page->page,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
							    0, PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
							    DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
				if (dma_mapping_error(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
						      ps_page->dma)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
					dev_err(&adapter->pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
						"Rx DMA page map failed\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
					adapter->rx_dma_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
					goto no_buffers;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
				}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
			 * Refresh the desc even if buffer_addrs
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
			 * didn't change because each write-back
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
			 * erases this info.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
			rx_desc->read.buffer_addr[j + 1] =
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
			    cpu_to_le64(ps_page->dma);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
		skb = __netdev_alloc_skb_ip_align(netdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
						  adapter->rx_ps_bsize0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
						  gfp);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
		if (!skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
			adapter->alloc_rx_buff_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
						  adapter->rx_ps_bsize0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
						  DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
			dev_err(&pdev->dev, "Rx DMA map failed\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
			adapter->rx_dma_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
			/* cleanup skb */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
			dev_kfree_skb_any(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
			buffer_info->skb = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
			 * Force memory writes to complete before letting h/w
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
			 * know there are new descriptors to fetch.  (Only
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
			 * applicable for weak-ordered memory model archs,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
			 * such as IA-64).
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
			wmb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
				e1000e_update_rdt_wa(rx_ring, i << 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
				writel(i << 1, rx_ring->tail);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
		i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
		if (i == rx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
			i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
		buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
no_buffers:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	rx_ring->next_to_use = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
 * @cleaned_count: number of buffers to allocate this pass
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
					 int cleaned_count, gfp_t gfp)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	union e1000_rx_desc_extended *rx_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	struct sk_buff *skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	unsigned int bufsz = 256 - 16 /* for skb_reserve */;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	i = rx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	while (cleaned_count--) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		skb = buffer_info->skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		if (skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
			skb_trim(skb, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
			goto check_page;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		if (unlikely(!skb)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
			/* Better luck next round */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
			adapter->alloc_rx_buff_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
check_page:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		/* allocate a new page if necessary */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		if (!buffer_info->page) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
			buffer_info->page = alloc_page(gfp);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
			if (unlikely(!buffer_info->page)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
				adapter->alloc_rx_buff_failed++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
				break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
		if (!buffer_info->dma)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
			buffer_info->dma = dma_map_page(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
			                                buffer_info->page, 0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
			                                PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
							DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		if (unlikely(++i == rx_ring->count))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
			i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	if (likely(rx_ring->next_to_use != i)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		rx_ring->next_to_use = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
		if (unlikely(i-- == 0))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
			i = (rx_ring->count - 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
		/* Force memory writes to complete before letting h/w
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
		 * know there are new descriptors to fetch.  (Only
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		 * applicable for weak-ordered memory model archs,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		 * such as IA-64). */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		wmb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
			e1000e_update_rdt_wa(rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
		else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
			writel(i, rx_ring->tail);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
				 struct sk_buff *skb)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	if (netdev->features & NETIF_F_RXHASH)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		skb->rxhash = le32_to_cpu(rss);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
 * e1000_clean_rx_irq - Send received data up the network stack
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
 * the return value indicates whether actual cleaning was done, there
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
 * is no guarantee that everything was cleaned
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
			       int work_to_do)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
	struct e1000_buffer *buffer_info, *next_buffer;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	u32 length, staterr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
	int cleaned_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	bool cleaned = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	i = rx_ring->next_to_clean;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	while (staterr & E1000_RXD_STAT_DD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		struct sk_buff *skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		if (*work_done >= work_to_do)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		(*work_done)++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		rmb();	/* read descriptor and rx_buffer_info after status DD */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		skb = buffer_info->skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		buffer_info->skb = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
		prefetch(skb->data - NET_IP_ALIGN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		if (i == rx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
			i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		prefetch(next_rxd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		next_buffer = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		cleaned = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		cleaned_count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		dma_unmap_single(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
				 buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
				 adapter->rx_buffer_len,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
				 DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		buffer_info->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		length = le16_to_cpu(rx_desc->wb.upper.length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		 * !EOP means multiple descriptors were used to store a single
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		 * packet, if that's the case we need to toss it.  In fact, we
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
		 * need to toss every packet with the EOP bit clear and the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		 * next frame that _does_ have the EOP bit set, as it is by
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
		 * definition only a frame fragment
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		if (unlikely(!(staterr & E1000_RXD_STAT_EOP)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
			adapter->flags2 |= FLAG2_IS_DISCARDING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
			/* All receives must fit into a single buffer */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
			e_dbg("Receive packet consumed multiple buffers\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
			/* recycle */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
			buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
			if (staterr & E1000_RXD_STAT_EOP)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
			     !(netdev->features & NETIF_F_RXALL))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
			/* recycle */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
			buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
		/* adjust length to remove Ethernet CRC */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
			/* If configured to store CRC, don't subtract FCS,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
			 * but keep the FCS bytes out of the total_rx_bytes
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
			 * counter
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
			if (netdev->features & NETIF_F_RXFCS)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
				total_rx_bytes -= 4;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
				length -= 4;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		total_rx_bytes += length;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		total_rx_packets++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		 * code added for copybreak, this should improve
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		 * performance for small packets with large amounts
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
		 * of reassembly being done in the stack
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		if (length < copybreak) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
			struct sk_buff *new_skb =
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
			    netdev_alloc_skb_ip_align(netdev, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
			if (new_skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
				skb_copy_to_linear_data_offset(new_skb,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
							       -NET_IP_ALIGN,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
							       (skb->data -
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
								NET_IP_ALIGN),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
							       (length +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
								NET_IP_ALIGN));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
				/* save the skb in buffer_info as good */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
				buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
				skb = new_skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
			/* else just continue with the old one */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
		/* end copybreak code */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
		skb_put(skb, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
		/* Receive Checksum Offload */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
		e1000_rx_checksum(adapter, staterr, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		e1000_receive_skb(adapter, netdev, skb, staterr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
				  rx_desc->wb.upper.vlan);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
next_desc:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		/* return some buffers to hardware, one at a time is too slow */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
					      GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
			cleaned_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
		/* use prefetched values */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
		rx_desc = next_rxd;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
		buffer_info = next_buffer;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
	rx_ring->next_to_clean = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	cleaned_count = e1000_desc_unused(rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	if (cleaned_count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	adapter->total_rx_bytes += total_rx_bytes;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	adapter->total_rx_packets += total_rx_packets;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	return cleaned;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
static void e1000_put_txbuf(struct e1000_ring *tx_ring,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
			    struct e1000_buffer *buffer_info)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
	if (buffer_info->dma) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
		if (buffer_info->mapped_as_page)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
				       buffer_info->length, DMA_TO_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
		else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
					 buffer_info->length, DMA_TO_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		buffer_info->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	if (buffer_info->skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		dev_kfree_skb_any(buffer_info->skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		buffer_info->skb = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	buffer_info->time_stamp = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
static void e1000_print_hw_hang(struct work_struct *work)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	struct e1000_adapter *adapter = container_of(work,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
	                                             struct e1000_adapter,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	                                             print_hang_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	struct e1000_ring *tx_ring = adapter->tx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	unsigned int i = tx_ring->next_to_clean;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
	u16 phy_status, phy_1000t_status, phy_ext_status;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	u16 pci_status;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	if (test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	if (!adapter->tx_hang_recheck &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	    (adapter->flags2 & FLAG2_DMA_BURST)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		/* May be block on write-back, flush and detect again
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		 * flush pending descriptor writebacks to memory
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		/* execute the writes immediately */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		 * Due to rare timing issues, write to TIDV again to ensure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		 * the write is successful
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		/* execute the writes immediately */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		adapter->tx_hang_recheck = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	/* Real hang detected */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	adapter->tx_hang_recheck = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	netif_stop_queue(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	e1e_rphy(hw, PHY_STATUS, &phy_status);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	/* detected Hardware unit hang */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	e_err("Detected Hardware Unit Hang:\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	      "  TDH                  <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	      "  TDT                  <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	      "  next_to_use          <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	      "  next_to_clean        <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	      "buffer_info[next_to_clean]:\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	      "  time_stamp           <%lx>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	      "  next_to_watch        <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	      "  jiffies              <%lx>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	      "  next_to_watch.status <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	      "MAC Status             <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	      "PHY Status             <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	      "PHY 1000BASE-T Status  <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	      "PHY Extended Status    <%x>\n"
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	      "PCI Status             <%x>\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	      readl(tx_ring->head),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	      readl(tx_ring->tail),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	      tx_ring->next_to_use,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	      tx_ring->next_to_clean,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	      tx_ring->buffer_info[eop].time_stamp,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	      eop,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	      jiffies,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	      eop_desc->upper.fields.status,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	      er32(STATUS),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	      phy_status,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	      phy_1000t_status,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
	      phy_ext_status,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	      pci_status);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
 * @tx_ring: Tx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
 * the return value indicates whether actual cleaning was done, there
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
 * is no guarantee that everything was cleaned
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	struct e1000_tx_desc *tx_desc, *eop_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	unsigned int i, eop;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	unsigned int count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	unsigned int bytes_compl = 0, pkts_compl = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
	i = tx_ring->next_to_clean;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
	eop = tx_ring->buffer_info[i].next_to_watch;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	       (count < tx_ring->count)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		bool cleaned = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		rmb(); /* read buffer_info after eop_desc */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
		for (; !cleaned; count++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
			tx_desc = E1000_TX_DESC(*tx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
			buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
			cleaned = (i == eop);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
			if (cleaned) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
				total_tx_packets += buffer_info->segs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
				total_tx_bytes += buffer_info->bytecount;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
				if (buffer_info->skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
					bytes_compl += buffer_info->skb->len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
					pkts_compl++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
				}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			e1000_put_txbuf(tx_ring, buffer_info);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			tx_desc->upper.data = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
			i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
			if (i == tx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
				i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		if (i == tx_ring->next_to_use)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		eop = tx_ring->buffer_info[i].next_to_watch;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	tx_ring->next_to_clean = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
#define TX_WAKE_THRESHOLD 32
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	if (count && netif_carrier_ok(netdev) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		/* Make sure that anybody stopping the queue after this
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		 * sees the new next_to_clean.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
		smp_mb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		if (netif_queue_stopped(netdev) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
			netif_wake_queue(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
			++adapter->restart_queue;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	if (adapter->detect_tx_hung) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
		 * Detect a transmit hang in hardware, this serializes the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
		 * check with the clearing of time_stamp and movement of i
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
		adapter->detect_tx_hung = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		if (tx_ring->buffer_info[i].time_stamp &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
			       + (adapter->tx_timeout_factor * HZ)) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		    !(er32(STATUS) & E1000_STATUS_TXOFF))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			schedule_work(&adapter->print_hang_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
			adapter->tx_hang_recheck = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	adapter->total_tx_bytes += total_tx_bytes;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	adapter->total_tx_packets += total_tx_packets;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	return count < tx_ring->count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
 * the return value indicates whether actual cleaning was done, there
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
 * is no guarantee that everything was cleaned
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
				  int work_to_do)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
	struct e1000_buffer *buffer_info, *next_buffer;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
	struct e1000_ps_page *ps_page;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
	struct sk_buff *skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
	unsigned int i, j;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
	u32 length, staterr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
	int cleaned_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	bool cleaned = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	i = rx_ring->next_to_clean;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	while (staterr & E1000_RXD_STAT_DD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		if (*work_done >= work_to_do)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		(*work_done)++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		skb = buffer_info->skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		rmb();	/* read descriptor and rx_buffer_info after status DD */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		/* in the packet split case this is header only */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		prefetch(skb->data - NET_IP_ALIGN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		if (i == rx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
			i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		prefetch(next_rxd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		next_buffer = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		cleaned = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		cleaned_count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		dma_unmap_single(&pdev->dev, buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
				 adapter->rx_ps_bsize0, DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		buffer_info->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
		/* see !EOP comment in other Rx routine */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
		if (!(staterr & E1000_RXD_STAT_EOP))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
			adapter->flags2 |= FLAG2_IS_DISCARDING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
			e_dbg("Packet Split buffers didn't pick up the full packet\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
			dev_kfree_skb_irq(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
			if (staterr & E1000_RXD_STAT_EOP)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
			     !(netdev->features & NETIF_F_RXALL))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
			dev_kfree_skb_irq(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
		length = le16_to_cpu(rx_desc->wb.middle.length0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		if (!length) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
			e_dbg("Last part of the packet spanning multiple descriptors\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
			dev_kfree_skb_irq(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		/* Good Receive */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		skb_put(skb, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
			 * this looks ugly, but it seems compiler issues make
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
			 * it more efficient than reusing j
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
			int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
			 * page alloc/put takes too long and effects small
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
			 * packet throughput, so unsplit small packets and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
			 * save the alloc/put only valid in softirq (napi)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
			 * context to call kmap_*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
			if (l1 && (l1 <= copybreak) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
			    ((length + l1) <= adapter->rx_ps_bsize0)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
				u8 *vaddr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
				ps_page = &buffer_info->ps_pages[0];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
				/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
				 * there is no documentation about how to call
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
				 * kmap_atomic, so we can't hold the mapping
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
				 * very long
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
				 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
				dma_sync_single_for_cpu(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
							ps_page->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
							PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
							DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
				vaddr = kmap_atomic(ps_page->page);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
				memcpy(skb_tail_pointer(skb), vaddr, l1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
				kunmap_atomic(vaddr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
				dma_sync_single_for_device(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
							   ps_page->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
							   PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
							   DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
				/* remove the CRC */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
				if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
					if (!(netdev->features & NETIF_F_RXFCS))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
						l1 -= 4;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
				}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
				skb_put(skb, l1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
				goto copydone;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
			} /* if */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
			if (!length)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
				break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
			ps_page = &buffer_info->ps_pages[j];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
				       DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
			ps_page->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
			skb_fill_page_desc(skb, j, ps_page->page, 0, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
			ps_page->page = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
			skb->len += length;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
			skb->data_len += length;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
			skb->truesize += PAGE_SIZE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
		/* strip the ethernet crc, problem is we're using pages now so
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
		 * this whole operation can get a little cpu intensive
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
			if (!(netdev->features & NETIF_F_RXFCS))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
				pskb_trim(skb, skb->len - 4);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
copydone:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		total_rx_bytes += skb->len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		total_rx_packets++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
		e1000_rx_checksum(adapter, staterr, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		if (rx_desc->wb.upper.header_status &
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
			adapter->rx_hdr_split++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
		e1000_receive_skb(adapter, netdev, skb,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
				  staterr, rx_desc->wb.middle.vlan);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
next_desc:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
		buffer_info->skb = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		/* return some buffers to hardware, one at a time is too slow */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
					      GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
			cleaned_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
		/* use prefetched values */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
		rx_desc = next_rxd;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
		buffer_info = next_buffer;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
	rx_ring->next_to_clean = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	cleaned_count = e1000_desc_unused(rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	if (cleaned_count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	adapter->total_rx_bytes += total_rx_bytes;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	adapter->total_rx_packets += total_rx_packets;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
	return cleaned;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
 * e1000_consume_page - helper function
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
                               u16 length)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	bi->page = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
	skb->len += length;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	skb->data_len += length;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	skb->truesize += PAGE_SIZE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
 * the return value indicates whether actual cleaning was done, there
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
 * is no guarantee that everything was cleaned
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
				     int work_to_do)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	struct e1000_buffer *buffer_info, *next_buffer;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	u32 length, staterr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	int cleaned_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	bool cleaned = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	unsigned int total_rx_bytes=0, total_rx_packets=0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	i = rx_ring->next_to_clean;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	while (staterr & E1000_RXD_STAT_DD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
		struct sk_buff *skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
		if (*work_done >= work_to_do)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		(*work_done)++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		rmb();	/* read descriptor and rx_buffer_info after status DD */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
		skb = buffer_info->skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
		buffer_info->skb = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		++i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
		if (i == rx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
			i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		prefetch(next_rxd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		next_buffer = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
		cleaned = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
		cleaned_count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
		dma_unmap_page(&pdev->dev, buffer_info->dma, PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
			       DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		buffer_info->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		length = le16_to_cpu(rx_desc->wb.upper.length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
		/* errors is only valid for DD + EOP descriptors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
		if (unlikely((staterr & E1000_RXD_STAT_EOP) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
			     ((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
			      !(netdev->features & NETIF_F_RXALL)))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
			/* recycle both page and skb */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
			buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
			/* an error means any chain goes out the window too */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
			if (rx_ring->rx_skb_top)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
				dev_kfree_skb_irq(rx_ring->rx_skb_top);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
			rx_ring->rx_skb_top = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
#define rxtop (rx_ring->rx_skb_top)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		if (!(staterr & E1000_RXD_STAT_EOP)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
			/* this descriptor is only the beginning (or middle) */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
			if (!rxtop) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
				/* this is the beginning of a chain */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
				rxtop = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
				                   0, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
			} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
				/* this is the middle of a chain */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
				skb_fill_page_desc(rxtop,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
				    skb_shinfo(rxtop)->nr_frags,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
				    buffer_info->page, 0, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
				/* re-use the skb, only consumed the page */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
				buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
			e1000_consume_page(buffer_info, rxtop, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
			if (rxtop) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
				/* end of the chain */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
				skb_fill_page_desc(rxtop,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
				    skb_shinfo(rxtop)->nr_frags,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
				    buffer_info->page, 0, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
				/* re-use the current skb, we only consumed the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
				 * page */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
				buffer_info->skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
				skb = rxtop;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
				rxtop = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
				e1000_consume_page(buffer_info, skb, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
			} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
				/* no chain, got EOP, this buf is the packet
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
				 * copybreak to save the put_page/alloc_page */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
				if (length <= copybreak &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
				    skb_tailroom(skb) >= length) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
					u8 *vaddr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
					vaddr = kmap_atomic(buffer_info->page);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
					memcpy(skb_tail_pointer(skb), vaddr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
					       length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
					kunmap_atomic(vaddr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
					/* re-use the page, so don't erase
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
					 * buffer_info->page */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
					skb_put(skb, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
				} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
					skb_fill_page_desc(skb, 0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
					                   buffer_info->page, 0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
				                           length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
					e1000_consume_page(buffer_info, skb,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
					                   length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
				}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		/* Receive Checksum Offload */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		e1000_rx_checksum(adapter, staterr, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		/* probably a little skewed due to removing CRC */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
		total_rx_bytes += skb->len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
		total_rx_packets++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		/* eth type trans needs skb->data to point to something */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		if (!pskb_may_pull(skb, ETH_HLEN)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
			e_err("pskb_may_pull failed.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
			dev_kfree_skb_irq(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
			goto next_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
		e1000_receive_skb(adapter, netdev, skb, staterr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
				  rx_desc->wb.upper.vlan);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
next_desc:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		/* return some buffers to hardware, one at a time is too slow */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
					      GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
			cleaned_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		/* use prefetched values */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		rx_desc = next_rxd;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		buffer_info = next_buffer;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	rx_ring->next_to_clean = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
	cleaned_count = e1000_desc_unused(rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	if (cleaned_count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
	adapter->total_rx_bytes += total_rx_bytes;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	adapter->total_rx_packets += total_rx_packets;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	return cleaned;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	struct e1000_ps_page *ps_page;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	unsigned int i, j;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
	/* Free all the Rx ring sk_buffs */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
	for (i = 0; i < rx_ring->count; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
		buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
		if (buffer_info->dma) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
			if (adapter->clean_rx == e1000_clean_rx_irq)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
				dma_unmap_single(&pdev->dev, buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
						 adapter->rx_buffer_len,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
						 DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
				dma_unmap_page(&pdev->dev, buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
				               PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
					       DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
				dma_unmap_single(&pdev->dev, buffer_info->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
						 adapter->rx_ps_bsize0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
						 DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
			buffer_info->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		if (buffer_info->page) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
			put_page(buffer_info->page);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
			buffer_info->page = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		if (buffer_info->skb) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
			dev_kfree_skb(buffer_info->skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
			buffer_info->skb = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
			ps_page = &buffer_info->ps_pages[j];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
			if (!ps_page->page)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
				break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
				       DMA_FROM_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
			ps_page->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
			put_page(ps_page->page);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
			ps_page->page = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	/* there also may be some cached data from a chained receive */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	if (rx_ring->rx_skb_top) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
		dev_kfree_skb(rx_ring->rx_skb_top);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
		rx_ring->rx_skb_top = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	/* Zero out the descriptor ring */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	memset(rx_ring->desc, 0, rx_ring->size);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	rx_ring->next_to_clean = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	rx_ring->next_to_use = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	writel(0, rx_ring->head);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	writel(0, rx_ring->tail);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
static void e1000e_downshift_workaround(struct work_struct *work)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	struct e1000_adapter *adapter = container_of(work,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
					struct e1000_adapter, downshift_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	if (test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 * e1000_intr_msi - Interrupt Handler
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
 * @irq: interrupt number
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
 * @data: pointer to a network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
static irqreturn_t e1000_intr_msi(int irq, void *data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	struct net_device *netdev = data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	u32 icr = er32(ICR);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	 * read ICR disables interrupts using IAM
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	if (icr & E1000_ICR_LSC) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
		hw->mac.get_link_status = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
		 * ICH8 workaround-- Call gig speed drop workaround on cable
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		 * disconnect (LSC) before accessing any PHY registers
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		    (!(er32(STATUS) & E1000_STATUS_LU)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
			schedule_work(&adapter->downshift_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		 * 80003ES2LAN workaround-- For packet buffer work-around on
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		 * link down event; disable receives here in the ISR and reset
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		 * adapter in watchdog
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		if (netif_carrier_ok(netdev) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
			/* disable receives */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
			u32 rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
			adapter->flags |= FLAG_RX_RESTART_NOW;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		/* guard against interrupt when we're going down */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	if (napi_schedule_prep(&adapter->napi)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		adapter->total_tx_bytes = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		adapter->total_tx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		adapter->total_rx_bytes = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
		adapter->total_rx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
		__napi_schedule(&adapter->napi);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	return IRQ_HANDLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
 * e1000_intr - Interrupt Handler
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
 * @irq: interrupt number
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
 * @data: pointer to a network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
static irqreturn_t e1000_intr(int irq, void *data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	struct net_device *netdev = data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	u32 rctl, icr = er32(ICR);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
		return IRQ_NONE;  /* Not our interrupt */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	 * IMS will not auto-mask if INT_ASSERTED is not set, and if it is
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	 * not set, then the adapter didn't send an interrupt
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	if (!(icr & E1000_ICR_INT_ASSERTED))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
		return IRQ_NONE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	 * Interrupt Auto-Mask...upon reading ICR,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	 * interrupts are masked.  No need for the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
	 * IMC write
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
	if (icr & E1000_ICR_LSC) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		hw->mac.get_link_status = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		 * ICH8 workaround-- Call gig speed drop workaround on cable
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		 * disconnect (LSC) before accessing any PHY registers
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		    (!(er32(STATUS) & E1000_STATUS_LU)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
			schedule_work(&adapter->downshift_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		 * 80003ES2LAN workaround--
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		 * For packet buffer work-around on link down event;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		 * disable receives here in the ISR and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
		 * reset adapter in watchdog
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		if (netif_carrier_ok(netdev) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
			/* disable receives */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
			rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
			adapter->flags |= FLAG_RX_RESTART_NOW;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		/* guard against interrupt when we're going down */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
		if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	if (napi_schedule_prep(&adapter->napi)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
		adapter->total_tx_bytes = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
		adapter->total_tx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		adapter->total_rx_bytes = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
		adapter->total_rx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
		__napi_schedule(&adapter->napi);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	return IRQ_HANDLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
static irqreturn_t e1000_msix_other(int irq, void *data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
	struct net_device *netdev = data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
	u32 icr = er32(ICR);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
			ew32(IMS, E1000_IMS_OTHER);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		return IRQ_NONE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	if (icr & adapter->eiac_mask)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		ew32(ICS, (icr & adapter->eiac_mask));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	if (icr & E1000_ICR_OTHER) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		if (!(icr & E1000_ICR_LSC))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
			goto no_link_interrupt;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		hw->mac.get_link_status = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		/* guard against interrupt when we're going down */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
no_link_interrupt:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	return IRQ_HANDLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
static irqreturn_t e1000_intr_msix_tx(int irq, void *data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	struct net_device *netdev = data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
	struct e1000_ring *tx_ring = adapter->tx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	adapter->total_tx_bytes = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	adapter->total_tx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
	if (!e1000_clean_tx_irq(tx_ring))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		/* Ring was not completely cleaned, so fire another interrupt */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		ew32(ICS, tx_ring->ims_val);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	return IRQ_HANDLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	struct net_device *netdev = data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	struct e1000_ring *rx_ring = adapter->rx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	/* Write the ITR value calculated at the end of the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	 * previous interrupt.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	if (rx_ring->set_itr) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		writel(1000000000 / (rx_ring->itr_val * 256),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
		       rx_ring->itr_register);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
		rx_ring->set_itr = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	if (napi_schedule_prep(&adapter->napi)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
		adapter->total_rx_bytes = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		adapter->total_rx_packets = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
		__napi_schedule(&adapter->napi);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
	return IRQ_HANDLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
 * e1000_configure_msix - Configure MSI-X hardware
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
 * e1000_configure_msix sets up the hardware to properly
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
 * generate MSI-X interrupts.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
static void e1000_configure_msix(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
	struct e1000_ring *rx_ring = adapter->rx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	struct e1000_ring *tx_ring = adapter->tx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	int vector = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	u32 ctrl_ext, ivar = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	adapter->eiac_mask = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	if (hw->mac.type == e1000_82574) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		u32 rfctl = er32(RFCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
		rfctl |= E1000_RFCTL_ACK_DIS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		ew32(RFCTL, rfctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
#define E1000_IVAR_INT_ALLOC_VALID	0x8
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	/* Configure Rx vector */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
	rx_ring->ims_val = E1000_IMS_RXQ0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	adapter->eiac_mask |= rx_ring->ims_val;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	if (rx_ring->itr_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		writel(1000000000 / (rx_ring->itr_val * 256),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
		       rx_ring->itr_register);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
		writel(1, rx_ring->itr_register);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	/* Configure Tx vector */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	tx_ring->ims_val = E1000_IMS_TXQ0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	if (tx_ring->itr_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		writel(1000000000 / (tx_ring->itr_val * 256),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
		       tx_ring->itr_register);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		writel(1, tx_ring->itr_register);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	adapter->eiac_mask |= tx_ring->ims_val;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	/* set vector for Other Causes, e.g. link changes */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
	vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
	if (rx_ring->itr_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		writel(1000000000 / (rx_ring->itr_val * 256),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		       hw->hw_addr + E1000_EITR_82574(vector));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	/* Cause Tx interrupts on every write back */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	ivar |= (1 << 31);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
	ew32(IVAR, ivar);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	/* enable MSI-X PBA support */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
	ctrl_ext = er32(CTRL_EXT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	/* Auto-Mask Other interrupts upon ICR read */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
#define E1000_EIAC_MASK_82574   0x01F00000
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	ew32(CTRL_EXT, ctrl_ext);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
	if (adapter->msix_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
		pci_disable_msix(adapter->pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
		kfree(adapter->msix_entries);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
		adapter->msix_entries = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
		pci_disable_msi(adapter->pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		adapter->flags &= ~FLAG_MSI_ENABLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
 * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
 * Attempt to configure interrupts using the best available
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 * capabilities of the hardware and kernel.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	int err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	switch (adapter->int_mode) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	case E1000E_INT_MODE_MSIX:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
		if (adapter->flags & FLAG_HAS_MSIX) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
			adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
			adapter->msix_entries = kcalloc(adapter->num_vectors,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
						      sizeof(struct msix_entry),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
						      GFP_KERNEL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
			if (adapter->msix_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
				for (i = 0; i < adapter->num_vectors; i++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
					adapter->msix_entries[i].entry = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
				err = pci_enable_msix(adapter->pdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
						      adapter->msix_entries,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
						      adapter->num_vectors);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
				if (err == 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
					return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
			/* MSI-X failed, so fall through and try MSI */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
			e_err("Failed to initialize MSI-X interrupts.  Falling back to MSI interrupts.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
			e1000e_reset_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
		adapter->int_mode = E1000E_INT_MODE_MSI;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		/* Fall through */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	case E1000E_INT_MODE_MSI:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
		if (!pci_enable_msi(adapter->pdev)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			adapter->flags |= FLAG_MSI_ENABLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
			e_err("Failed to initialize MSI interrupts.  Falling back to legacy interrupts.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		/* Fall through */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	case E1000E_INT_MODE_LEGACY:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		/* Don't do anything; this is the system default */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
	/* store the number of vectors being used */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	adapter->num_vectors = 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
 * e1000_request_msix - Initialize MSI-X interrupts
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
 * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
 * kernel.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
static int e1000_request_msix(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	int err = 0, vector = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		snprintf(adapter->rx_ring->name,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
			 sizeof(adapter->rx_ring->name) - 1,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
			 "%s-rx-0", netdev->name);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	err = request_irq(adapter->msix_entries[vector].vector,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
			  netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	adapter->rx_ring->itr_register = adapter->hw.hw_addr +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	    E1000_EITR_82574(vector);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	adapter->rx_ring->itr_val = adapter->itr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
		snprintf(adapter->tx_ring->name,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
			 sizeof(adapter->tx_ring->name) - 1,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
			 "%s-tx-0", netdev->name);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	err = request_irq(adapter->msix_entries[vector].vector,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
			  netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	adapter->tx_ring->itr_register = adapter->hw.hw_addr +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	    E1000_EITR_82574(vector);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	adapter->tx_ring->itr_val = adapter->itr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	err = request_irq(adapter->msix_entries[vector].vector,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
			  e1000_msix_other, 0, netdev->name, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	e1000_configure_msix(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
 * e1000_request_irq - initialize interrupts
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
 * Attempts to configure interrupts using the best available
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
 * capabilities of the hardware and kernel.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
static int e1000_request_irq(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	int err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	if (adapter->msix_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		err = e1000_request_msix(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
		if (!err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
			return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
		/* fall back to MSI */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
		e1000e_reset_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		adapter->int_mode = E1000E_INT_MODE_MSI;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
		e1000e_set_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
	if (adapter->flags & FLAG_MSI_ENABLED) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
		err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
				  netdev->name, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		if (!err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
			return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		/* fall back to legacy interrupt */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		e1000e_reset_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
			  netdev->name, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
		e_err("Unable to allocate interrupt, Error: %d\n", err);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
static void e1000_free_irq(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	if (adapter->msix_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
		int vector = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
		free_irq(adapter->msix_entries[vector].vector, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
		vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
		free_irq(adapter->msix_entries[vector].vector, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
		vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
		/* Other Causes interrupt vector */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		free_irq(adapter->msix_entries[vector].vector, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	free_irq(adapter->pdev->irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
 * e1000_irq_disable - Mask off interrupt generation on the NIC
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
static void e1000_irq_disable(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	ew32(IMC, ~0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	if (adapter->msix_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
		ew32(EIAC_82574, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	if (adapter->msix_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		for (i = 0; i < adapter->num_vectors; i++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
			synchronize_irq(adapter->msix_entries[i].vector);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
		synchronize_irq(adapter->pdev->irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
 * e1000_irq_enable - Enable default interrupt generation settings
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
static void e1000_irq_enable(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	if (adapter->msix_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		ew32(IMS, IMS_ENABLE_MASK);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
 * e1000e_get_hw_control - get control of the h/w from f/w
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
 * @adapter: address of board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
 * e1000e_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
 * For ASF and Pass Through versions of f/w this means that
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
 * the driver is loaded. For AMT version (only with 82573)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
 * of the f/w this means that the network i/f is open.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
void e1000e_get_hw_control(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	u32 ctrl_ext;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	u32 swsm;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	/* Let firmware know the driver has taken over */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		swsm = er32(SWSM);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		ctrl_ext = er32(CTRL_EXT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
 * e1000e_release_hw_control - release control of the h/w to f/w
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
 * @adapter: address of board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
 * e1000e_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
 * For ASF and Pass Through versions of f/w this means that the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
 * driver is no longer loaded. For AMT version (only with 82573) i
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
 * of the f/w this means that the network i/f is closed.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
void e1000e_release_hw_control(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	u32 ctrl_ext;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	u32 swsm;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
	/* Let firmware taken over control of h/w */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
		swsm = er32(SWSM);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
		ctrl_ext = er32(CTRL_EXT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
 * @e1000_alloc_ring - allocate memory for a ring structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
				struct e1000_ring *ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
					GFP_KERNEL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	if (!ring->desc)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
		return -ENOMEM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
 * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
 * @tx_ring: Tx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
 * Return 0 on success, negative on failure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
int e1000e_setup_tx_resources(struct e1000_ring *tx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	int err = -ENOMEM, size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	size = sizeof(struct e1000_buffer) * tx_ring->count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
	tx_ring->buffer_info = vzalloc(size);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	if (!tx_ring->buffer_info)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
		goto err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	/* round up to nearest 4K */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	tx_ring->size = ALIGN(tx_ring->size, 4096);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	err = e1000_alloc_ring_dma(adapter, tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		goto err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
	tx_ring->next_to_use = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	tx_ring->next_to_clean = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
err:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
	vfree(tx_ring->buffer_info);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
 * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
 * Returns 0 on success, negative on failure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
int e1000e_setup_rx_resources(struct e1000_ring *rx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	int i, size, desc_len, err = -ENOMEM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	size = sizeof(struct e1000_buffer) * rx_ring->count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	rx_ring->buffer_info = vzalloc(size);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	if (!rx_ring->buffer_info)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		goto err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
	for (i = 0; i < rx_ring->count; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
		buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
						sizeof(struct e1000_ps_page),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
						GFP_KERNEL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
		if (!buffer_info->ps_pages)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
			goto err_pages;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	desc_len = sizeof(union e1000_rx_desc_packet_split);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	/* Round up to nearest 4K */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	rx_ring->size = rx_ring->count * desc_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	rx_ring->size = ALIGN(rx_ring->size, 4096);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	err = e1000_alloc_ring_dma(adapter, rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
		goto err_pages;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
	rx_ring->next_to_clean = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	rx_ring->next_to_use = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	rx_ring->rx_skb_top = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
err_pages:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
	for (i = 0; i < rx_ring->count; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		buffer_info = &rx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
		kfree(buffer_info->ps_pages);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
err:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	vfree(rx_ring->buffer_info);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
	e_err("Unable to allocate memory for the receive descriptor ring\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
	return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
 * e1000_clean_tx_ring - Free Tx Buffers
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
 * @tx_ring: Tx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	unsigned long size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	for (i = 0; i < tx_ring->count; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
		buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
		e1000_put_txbuf(tx_ring, buffer_info);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	netdev_reset_queue(adapter->netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	size = sizeof(struct e1000_buffer) * tx_ring->count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	memset(tx_ring->buffer_info, 0, size);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	memset(tx_ring->desc, 0, tx_ring->size);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	tx_ring->next_to_use = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	tx_ring->next_to_clean = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	writel(0, tx_ring->head);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	writel(0, tx_ring->tail);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
 * e1000e_free_tx_resources - Free Tx Resources per Queue
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
 * @tx_ring: Tx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
 * Free all transmit software resources
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
void e1000e_free_tx_resources(struct e1000_ring *tx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	e1000_clean_tx_ring(tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	vfree(tx_ring->buffer_info);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
	tx_ring->buffer_info = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
			  tx_ring->dma);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	tx_ring->desc = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
 * e1000e_free_rx_resources - Free Rx Resources
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
 * @rx_ring: Rx descriptor ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
 * Free all receive software resources
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
void e1000e_free_rx_resources(struct e1000_ring *rx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	struct e1000_adapter *adapter = rx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
	e1000_clean_rx_ring(rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	for (i = 0; i < rx_ring->count; i++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		kfree(rx_ring->buffer_info[i].ps_pages);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	vfree(rx_ring->buffer_info);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	rx_ring->buffer_info = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
			  rx_ring->dma);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	rx_ring->desc = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
 * e1000_update_itr - update the dynamic ITR value based on statistics
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
 * @adapter: pointer to adapter
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
 * @itr_setting: current adapter->itr
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
 * @packets: the number of packets during this measurement interval
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
 * @bytes: the number of bytes during this measurement interval
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
 *      Stores a new ITR value based on packets and byte
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
 *      counts during the last interrupt.  The advantage of per interrupt
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
 *      computation is faster updates and more accurate ITR for the current
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
 *      traffic pattern.  Constants in this function were computed
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
 *      based on theoretical maximum wire speed and thresholds were set based
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
 *      on testing data as well as attempting to minimize response time
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
 *      while increasing bulk throughput.  This functionality is controlled
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
 *      by the InterruptThrottleRate module parameter.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
				     u16 itr_setting, int packets,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
				     int bytes)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
	unsigned int retval = itr_setting;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	if (packets == 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
		return itr_setting;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	switch (itr_setting) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	case lowest_latency:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
		/* handle TSO and jumbo frames */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
		if (bytes/packets > 8000)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
			retval = bulk_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
		else if ((packets < 5) && (bytes > 512))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
			retval = low_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	case low_latency:  /* 50 usec aka 20000 ints/s */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		if (bytes > 10000) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
			/* this if handles the TSO accounting */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
			if (bytes/packets > 8000)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
				retval = bulk_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
			else if ((packets < 10) || ((bytes/packets) > 1200))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
				retval = bulk_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
			else if ((packets > 35))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
				retval = lowest_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		} else if (bytes/packets > 2000) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
			retval = bulk_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		} else if (packets <= 2 && bytes < 512) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
			retval = lowest_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	case bulk_latency: /* 250 usec aka 4000 ints/s */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		if (bytes > 25000) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
			if (packets > 35)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
				retval = low_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		} else if (bytes < 6000) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
			retval = low_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	return retval;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
static void e1000_set_itr(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	u16 current_itr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	u32 new_itr = adapter->itr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	if (adapter->link_speed != SPEED_1000) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
		current_itr = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
		new_itr = 4000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		goto set_itr_now;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	if (adapter->flags2 & FLAG2_DISABLE_AIM) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
		new_itr = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
		goto set_itr_now;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	adapter->tx_itr = e1000_update_itr(adapter,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
				    adapter->tx_itr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
				    adapter->total_tx_packets,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
				    adapter->total_tx_bytes);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
		adapter->tx_itr = low_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	adapter->rx_itr = e1000_update_itr(adapter,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
				    adapter->rx_itr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
				    adapter->total_rx_packets,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
				    adapter->total_rx_bytes);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		adapter->rx_itr = low_latency;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	switch (current_itr) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
	/* counts and packets in update_itr are dependent on these numbers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	case lowest_latency:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		new_itr = 70000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
	case low_latency:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
		new_itr = 20000; /* aka hwitr = ~200 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	case bulk_latency:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		new_itr = 4000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
set_itr_now:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	if (new_itr != adapter->itr) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
		 * this attempts to bias the interrupt rate towards Bulk
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
		 * by adding intermediate steps when interrupt rate is
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
		 * increasing
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
		new_itr = new_itr > adapter->itr ?
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
			     min(adapter->itr + (new_itr >> 2), new_itr) :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
			     new_itr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
		adapter->itr = new_itr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
		adapter->rx_ring->itr_val = new_itr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		if (adapter->msix_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
			adapter->rx_ring->set_itr = 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
		else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
			if (new_itr)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
				ew32(ITR, 1000000000 / (new_itr * 256));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
				ew32(ITR, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
 * e1000_alloc_queues - Allocate memory for all rings
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
 * @adapter: board private structure to initialize
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	int size = sizeof(struct e1000_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	adapter->tx_ring = kzalloc(size, GFP_KERNEL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	if (!adapter->tx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		goto err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	adapter->tx_ring->count = adapter->tx_ring_count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	adapter->tx_ring->adapter = adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	adapter->rx_ring = kzalloc(size, GFP_KERNEL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	if (!adapter->rx_ring)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		goto err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
	adapter->rx_ring->count = adapter->rx_ring_count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	adapter->rx_ring->adapter = adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
err:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	e_err("Unable to allocate memory for queues\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
	kfree(adapter->rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	kfree(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	return -ENOMEM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
 * e1000_clean - NAPI Rx polling callback
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
 * @napi: struct associated with this polling callback
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
 * @budget: amount of packets driver is allowed to process this poll
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
static int e1000_clean(struct napi_struct *napi, int budget)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
	struct net_device *poll_dev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
	int tx_cleaned = 1, work_done = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
	adapter = netdev_priv(poll_dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	if (adapter->msix_entries &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
	    !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
		goto clean_rx;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
	tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
clean_rx:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	adapter->clean_rx(adapter->rx_ring, &work_done, budget);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	if (!tx_cleaned)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
		work_done = budget;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
	/* If budget not fully consumed, exit the polling mode */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	if (work_done < budget) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
		if (adapter->itr_setting & 3)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
			e1000_set_itr(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
		napi_complete(napi);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
			if (adapter->msix_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
				ew32(IMS, adapter->rx_ring->ims_val);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
				e1000_irq_enable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	return work_done;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	u32 vfta, index;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
	/* don't update vlan cookie if already programmed */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	if ((adapter->hw.mng_cookie.status &
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
	    (vid == adapter->mng_vlan_id))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	/* add VID to filter table */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		index = (vid >> 5) & 0x7F;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
		vfta |= (1 << (vid & 0x1F));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
		hw->mac.ops.write_vfta(hw, index, vfta);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	set_bit(vid, adapter->active_vlans);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	u32 vfta, index;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	if ((adapter->hw.mng_cookie.status &
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	    (vid == adapter->mng_vlan_id)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
		/* release control to f/w */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		e1000e_release_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
	/* remove VID from filter table */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
		index = (vid >> 5) & 0x7F;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		vfta &= ~(1 << (vid & 0x1F));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
		hw->mac.ops.write_vfta(hw, index, vfta);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
	clear_bit(vid, adapter->active_vlans);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
 * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
 * @adapter: board private structure to initialize
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	u32 rctl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
		/* disable VLAN receive filtering */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
		rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
		rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
		ew32(RCTL, rctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
 * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
 * @adapter: board private structure to initialize
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	u32 rctl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
		/* enable VLAN receive filtering */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
		rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
		rctl |= E1000_RCTL_VFE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
		rctl &= ~E1000_RCTL_CFIEN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		ew32(RCTL, rctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
 * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
 * @adapter: board private structure to initialize
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	u32 ctrl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	/* disable VLAN tag insert/strip */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	ctrl = er32(CTRL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	ctrl &= ~E1000_CTRL_VME;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	ew32(CTRL, ctrl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
 * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
 * @adapter: board private structure to initialize
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	u32 ctrl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	/* enable VLAN tag insert/strip */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
	ctrl = er32(CTRL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
	ctrl |= E1000_CTRL_VME;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
	ew32(CTRL, ctrl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	u16 vid = adapter->hw.mng_cookie.vlan_id;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	u16 old_vid = adapter->mng_vlan_id;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	if (adapter->hw.mng_cookie.status &
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	    E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
		e1000_vlan_rx_add_vid(netdev, vid);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		adapter->mng_vlan_id = vid;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		e1000_vlan_rx_kill_vid(netdev, old_vid);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
static void e1000_restore_vlan(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	u16 vid;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	e1000_vlan_rx_add_vid(adapter->netdev, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		e1000_vlan_rx_add_vid(adapter->netdev, vid);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
	u32 manc, manc2h, mdef, i, j;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	manc = er32(MANC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	 * enable receiving management packets to the host. this will probably
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	 * generate destination unreachable messages from the host OS, but
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	 * the packets will be handled on SMBUS
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	manc |= E1000_MANC_EN_MNG2HOST;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	manc2h = er32(MANC2H);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	switch (hw->mac.type) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
		manc2h |= (E1000_MANC2H_PORT_623 | E1000_MANC2H_PORT_664);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
	case e1000_82574:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
	case e1000_82583:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		 * Check if IPMI pass-through decision filter already exists;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
		 * if so, enable it.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
		for (i = 0, j = 0; i < 8; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
			mdef = er32(MDEF(i));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
			/* Ignore filters with anything other than IPMI ports */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
			if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
				continue;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
			/* Enable this decision filter in MANC2H */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
			if (mdef)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
				manc2h |= (1 << i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
			j |= mdef;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
		if (j == (E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		/* Create new decision filter in an empty filter */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		for (i = 0, j = 0; i < 8; i++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
			if (er32(MDEF(i)) == 0) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
				ew32(MDEF(i), (E1000_MDEF_PORT_623 |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
					       E1000_MDEF_PORT_664));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
				manc2h |= (1 << 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
				j++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
				break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
		if (!j)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
			e_warn("Unable to create IPMI pass-through filter\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
	ew32(MANC2H, manc2h);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	ew32(MANC, manc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
 * e1000_configure_tx - Configure Transmit Unit after Reset
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
 * Configure the Tx unit of the MAC after a reset.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
static void e1000_configure_tx(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
	struct e1000_ring *tx_ring = adapter->tx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
	u64 tdba;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
	u32 tdlen, tarc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	/* Setup the HW Tx Head and Tail descriptor pointers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	tdba = tx_ring->dma;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	ew32(TDBAH, (tdba >> 32));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
	ew32(TDLEN, tdlen);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	ew32(TDH, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	ew32(TDT, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
	tx_ring->head = adapter->hw.hw_addr + E1000_TDH;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
	tx_ring->tail = adapter->hw.hw_addr + E1000_TDT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
	/* Set the Tx Interrupt Delay register */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
	ew32(TIDV, adapter->tx_int_delay);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	/* Tx irq moderation */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	ew32(TADV, adapter->tx_abs_int_delay);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	if (adapter->flags2 & FLAG2_DMA_BURST) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		u32 txdctl = er32(TXDCTL(0));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
			    E1000_TXDCTL_WTHRESH);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		 * set up some performance related parameters to encourage the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		 * hardware to use the bus more efficiently in bursts, depends
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		 * on the tx_int_delay to be enabled,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		 * wthresh = 1 ==> burst write is disabled to avoid Tx stalls
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
		 * hthresh = 1 ==> prefetch when one or more available
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
		 * pthresh = 0x1f ==> prefetch if internal cache 31 or less
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
		 * BEWARE: this seems to work but should be considered first if
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
		 * there are Tx hangs or other Tx related bugs
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
		txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
		ew32(TXDCTL(0), txdctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	/* erratum work around: set txdctl the same for both queues */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	ew32(TXDCTL(1), er32(TXDCTL(0)));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
		tarc = er32(TARC(0));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
		 * set the speed mode bit, we'll clear it if we're not at
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
		 * gigabit link later
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
#define SPEED_MODE_BIT (1 << 21)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
		tarc |= SPEED_MODE_BIT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		ew32(TARC(0), tarc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
	/* errata: program both queues to unweighted RR */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
		tarc = er32(TARC(0));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		tarc |= 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		ew32(TARC(0), tarc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		tarc = er32(TARC(1));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
		tarc |= 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		ew32(TARC(1), tarc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
	/* Setup Transmit Descriptor Settings for eop descriptor */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	/* only set IDE if we are delaying interrupts using the timers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	if (adapter->tx_int_delay)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
	/* enable Report Status bit */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
	hw->mac.ops.config_collision_dist(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
 * e1000_setup_rctl - configure the receive control registers
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
 * @adapter: Board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
static void e1000_setup_rctl(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	u32 rctl, rfctl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	u32 pages = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	/* Workaround Si errata on 82579 - configure jumbo frame flow */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	if (hw->mac.type == e1000_pch2lan) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
		s32 ret_val;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
		if (adapter->netdev->mtu > ETH_DATA_LEN)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
		else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
		if (ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
			e_dbg("failed to enable jumbo frame workaround mode\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	/* Program MC offset vector base */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	/* Do not Store bad packets */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	rctl &= ~E1000_RCTL_SBP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
	/* Enable Long Packet receive */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		rctl &= ~E1000_RCTL_LPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		rctl |= E1000_RCTL_LPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	/* Some systems expect that the CRC is included in SMBUS traffic. The
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	 * hardware strips the CRC before sending to both SMBUS (BMC) and to
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	 * host memory when this is enabled
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
		rctl |= E1000_RCTL_SECRC;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		u16 phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
		phy_data &= 0xfff8;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		phy_data |= (1 << 2);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		e1e_wphy(hw, PHY_REG(770, 26), phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
		e1e_rphy(hw, 22, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		phy_data &= 0x0fff;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		phy_data |= (1 << 14);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
		e1e_wphy(hw, 0x10, 0x2823);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
		e1e_wphy(hw, 0x11, 0x0003);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
		e1e_wphy(hw, 22, phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	/* Setup buffer sizes */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	rctl &= ~E1000_RCTL_SZ_4096;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	rctl |= E1000_RCTL_BSEX;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	switch (adapter->rx_buffer_len) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	case 2048:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
		rctl |= E1000_RCTL_SZ_2048;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		rctl &= ~E1000_RCTL_BSEX;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
	case 4096:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
		rctl |= E1000_RCTL_SZ_4096;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	case 8192:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		rctl |= E1000_RCTL_SZ_8192;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
	case 16384:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		rctl |= E1000_RCTL_SZ_16384;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	/* Enable Extended Status in all Receive Descriptors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	rfctl = er32(RFCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	rfctl |= E1000_RFCTL_EXTEN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	 * 82571 and greater support packet-split where the protocol
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	 * header is placed in skb->data and the packet data is
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	 * In the case of a non-split, skb->data is linearly filled,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	 * followed by the page buffers.  Therefore, skb->data is
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	 * sized to hold the largest protocol header.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	 * allocations using alloc_page take too long for regular MTU
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	 * so only enable packet split for jumbo frames
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	 * Using pages when the page size is greater than 16k wastes
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	 * a lot of memory, since we allocate 3 pages at all times
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	 * per packet.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
		adapter->rx_ps_pages = pages;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		adapter->rx_ps_pages = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
	if (adapter->rx_ps_pages) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
		u32 psrctl = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		 * disable packet split support for IPv6 extension headers,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
		 * because some malformed IPv6 headers can hang the Rx
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
			  E1000_RFCTL_NEW_IPV6_EXT_DIS);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
		/* Enable Packet split descriptors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
		rctl |= E1000_RCTL_DTYP_PS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
		psrctl |= adapter->rx_ps_bsize0 >>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
			E1000_PSRCTL_BSIZE0_SHIFT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		switch (adapter->rx_ps_pages) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
		case 3:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
			psrctl |= PAGE_SIZE <<
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
				E1000_PSRCTL_BSIZE3_SHIFT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		case 2:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
			psrctl |= PAGE_SIZE <<
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
				E1000_PSRCTL_BSIZE2_SHIFT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		case 1:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
			psrctl |= PAGE_SIZE >>
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
				E1000_PSRCTL_BSIZE1_SHIFT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		ew32(PSRCTL, psrctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	/* This is useful for sniffing bad packets. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	if (adapter->netdev->features & NETIF_F_RXALL) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		/* UPE and MPE will be handled by normal PROMISC logic
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
		 * in e1000e_set_rx_mode */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		rctl |= (E1000_RCTL_SBP | /* Receive bad packets */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
			 E1000_RCTL_BAM | /* RX All Bcast Pkts */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
			 E1000_RCTL_PMCF); /* RX All MAC Ctrl Pkts */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
		rctl &= ~(E1000_RCTL_VFE | /* Disable VLAN filter */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
			  E1000_RCTL_DPF | /* Allow filtered pause */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
			  E1000_RCTL_CFIEN); /* Dis VLAN CFIEN Filter */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
		 * and that breaks VLANs.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	ew32(RFCTL, rfctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	ew32(RCTL, rctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
	/* just started the receive unit, no need to restart */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	adapter->flags &= ~FLAG_RX_RESTART_NOW;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
 * e1000_configure_rx - Configure Receive Unit after Reset
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
 * Configure the Rx unit of the MAC after a reset.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
static void e1000_configure_rx(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	struct e1000_ring *rx_ring = adapter->rx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	u64 rdba;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	u32 rdlen, rctl, rxcsum, ctrl_ext;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	if (adapter->rx_ps_pages) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
		/* this is a 32 byte descriptor */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
		rdlen = rx_ring->count *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
		    sizeof(union e1000_rx_desc_packet_split);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		adapter->clean_rx = e1000_clean_rx_irq_ps;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		adapter->clean_rx = e1000_clean_rx_irq;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	/* disable receives while setting up the descriptors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	usleep_range(10000, 20000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	if (adapter->flags2 & FLAG2_DMA_BURST) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		 * set the writeback threshold (only takes effect if the RDTR
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
		 * is set). set GRAN=1 and write back up to 0x4 worth, and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		 * enable prefetching of 0x20 Rx descriptors
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		 * granularity = 01
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		 * wthresh = 04,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
		 * hthresh = 04,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
		 * pthresh = 0x20
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
		 * override the delay timers for enabling bursting, only if
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
		 * the value was not set by the user via module options
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		if (adapter->rx_int_delay == DEFAULT_RDTR)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
			adapter->rx_int_delay = BURST_RDTR;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
		if (adapter->rx_abs_int_delay == DEFAULT_RADV)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
			adapter->rx_abs_int_delay = BURST_RADV;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
	/* set the Receive Delay Timer Register */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
	ew32(RDTR, adapter->rx_int_delay);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
	/* irq moderation */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	ew32(RADV, adapter->rx_abs_int_delay);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	if ((adapter->itr_setting != 0) && (adapter->itr != 0))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		ew32(ITR, 1000000000 / (adapter->itr * 256));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
	ctrl_ext = er32(CTRL_EXT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	/* Auto-Mask interrupts upon ICR access */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	ctrl_ext |= E1000_CTRL_EXT_IAME;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	ew32(IAM, 0xffffffff);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	ew32(CTRL_EXT, ctrl_ext);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	 * Setup the HW Rx Head and Tail Descriptor Pointers and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
	 * the Base and Length of the Rx Descriptor Ring
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	rdba = rx_ring->dma;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	ew32(RDBAH, (rdba >> 32));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	ew32(RDLEN, rdlen);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	ew32(RDH, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	ew32(RDT, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	rx_ring->head = adapter->hw.hw_addr + E1000_RDH;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
	rx_ring->tail = adapter->hw.hw_addr + E1000_RDT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	/* Enable Receive Checksum Offload for TCP and UDP */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	rxcsum = er32(RXCSUM);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	if (adapter->netdev->features & NETIF_F_RXCSUM)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
		rxcsum |= E1000_RXCSUM_TUOFL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
		rxcsum &= ~E1000_RXCSUM_TUOFL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	ew32(RXCSUM, rxcsum);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	if (adapter->hw.mac.type == e1000_pch2lan) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
		 * With jumbo frames, excessive C-state transition
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
		 * latencies result in dropped transactions.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
			u32 rxdctl = er32(RXDCTL(0));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
			ew32(RXDCTL(0), rxdctl | 0x3);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
			pm_qos_update_request(&adapter->netdev->pm_qos_req, 55);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
			pm_qos_update_request(&adapter->netdev->pm_qos_req,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
					      PM_QOS_DEFAULT_VALUE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	/* Enable Receives */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
	ew32(RCTL, rctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
 * e1000e_write_mc_addr_list - write multicast addresses to MTA
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
 * Writes multicast address list to the MTA hash table.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
 * Returns: -ENOMEM on failure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
 *                0 on no addresses written
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
 *                X on writing X addresses to MTA
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
static int e1000e_write_mc_addr_list(struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	struct netdev_hw_addr *ha;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	u8 *mta_list;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
	if (netdev_mc_empty(netdev)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
		/* nothing to program, so clear mc list */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		hw->mac.ops.update_mc_addr_list(hw, NULL, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	mta_list = kzalloc(netdev_mc_count(netdev) * ETH_ALEN, GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	if (!mta_list)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		return -ENOMEM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
	/* update_mc_addr_list expects a packed array of only addresses. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
	i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
	netdev_for_each_mc_addr(ha, netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	hw->mac.ops.update_mc_addr_list(hw, mta_list, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
	kfree(mta_list);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
	return netdev_mc_count(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
 * e1000e_write_uc_addr_list - write unicast addresses to RAR table
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
 * Writes unicast address list to the RAR table.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
 * Returns: -ENOMEM on failure/insufficient address space
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
 *                0 on no addresses written
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
 *                X on writing X addresses to the RAR table
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
static int e1000e_write_uc_addr_list(struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	unsigned int rar_entries = hw->mac.rar_entry_count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	int count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	/* save a rar entry for our hardware address */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	rar_entries--;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	/* save a rar entry for the LAA workaround */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
		rar_entries--;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	/* return ENOMEM indicating insufficient memory for addresses */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	if (netdev_uc_count(netdev) > rar_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
		return -ENOMEM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	if (!netdev_uc_empty(netdev) && rar_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
		struct netdev_hw_addr *ha;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
		 * write the addresses in reverse order to avoid write
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
		 * combining
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
		netdev_for_each_uc_addr(ha, netdev) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
			if (!rar_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
				break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
			e1000e_rar_set(hw, ha->addr, rar_entries--);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
			count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	/* zero out the remaining RAR entries not used above */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	for (; rar_entries > 0; rar_entries--) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
		ew32(RAH(rar_entries), 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
		ew32(RAL(rar_entries), 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	return count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
 * e1000e_set_rx_mode - secondary unicast, Multicast and Promiscuous mode set
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
 * The ndo_set_rx_mode entry point is called whenever the unicast or multicast
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
 * address list or the network interface flags are updated.  This routine is
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
 * responsible for configuring the hardware for proper unicast, multicast,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
 * promiscuous mode, and all-multi behavior.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
static void e1000e_set_rx_mode(struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	u32 rctl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	/* Check for Promiscuous and All Multicast modes */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	/* clear the affected bits */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	if (netdev->flags & IFF_PROMISC) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
		/* Do not hardware filter VLANs in promisc mode */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
		e1000e_vlan_filter_disable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
		int count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
		if (netdev->flags & IFF_ALLMULTI) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
			rctl |= E1000_RCTL_MPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
			 * Write addresses to the MTA, if the attempt fails
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
			 * then we should just turn on promiscuous mode so
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
			 * that we can at least receive multicast traffic
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
			count = e1000e_write_mc_addr_list(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
			if (count < 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
				rctl |= E1000_RCTL_MPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
		e1000e_vlan_filter_enable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
		 * Write addresses to available RAR registers, if there is not
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		 * sufficient space to store all the addresses then enable
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
		 * unicast promiscuous mode
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
		count = e1000e_write_uc_addr_list(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
		if (count < 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
			rctl |= E1000_RCTL_UPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
	ew32(RCTL, rctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	if (netdev->features & NETIF_F_HW_VLAN_RX)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		e1000e_vlan_strip_enable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
		e1000e_vlan_strip_disable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
static void e1000e_setup_rss_hash(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	u32 mrqc, rxcsum;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	static const u32 rsskey[10] = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
		0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
		0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	/* Fill out hash function seed */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	for (i = 0; i < 10; i++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
		ew32(RSSRK(i), rsskey[i]);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	/* Direct all traffic to queue 0 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	for (i = 0; i < 32; i++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
		ew32(RETA(i), 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	 * Disable raw packet checksumming so that RSS hash is placed in
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	 * descriptor on writeback.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	rxcsum = er32(RXCSUM);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	rxcsum |= E1000_RXCSUM_PCSD;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	ew32(RXCSUM, rxcsum);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	mrqc = (E1000_MRQC_RSS_FIELD_IPV4 |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
		E1000_MRQC_RSS_FIELD_IPV4_TCP |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		E1000_MRQC_RSS_FIELD_IPV6 |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		E1000_MRQC_RSS_FIELD_IPV6_TCP |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
		E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	ew32(MRQC, mrqc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
 * e1000_configure - configure the hardware for Rx and Tx
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
 * @adapter: private board structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
static void e1000_configure(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	struct e1000_ring *rx_ring = adapter->rx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	e1000e_set_rx_mode(adapter->netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	e1000_restore_vlan(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	e1000_init_manageability_pt(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	e1000_configure_tx(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	if (adapter->netdev->features & NETIF_F_RXHASH)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		e1000e_setup_rss_hash(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	e1000_setup_rctl(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
	e1000_configure_rx(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
 * e1000e_power_up_phy - restore link in case the phy was powered down
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
 * @adapter: address of board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
 * The phy may be powered down to save power and turn off link when the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
 * driver is unloaded and wake on lan is not enabled (among others)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
 * *** this routine MUST be followed by a call to e1000e_reset ***
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
void e1000e_power_up_phy(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	if (adapter->hw.phy.ops.power_up)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
		adapter->hw.phy.ops.power_up(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	adapter->hw.mac.ops.setup_link(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
 * e1000_power_down_phy - Power down the PHY
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
 * Power down the PHY so no link is implied when interface is down.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
 * The PHY cannot be powered down if management or WoL is active.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
static void e1000_power_down_phy(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	/* WoL is enabled */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	if (adapter->wol)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	if (adapter->hw.phy.ops.power_down)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		adapter->hw.phy.ops.power_down(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
 * e1000e_reset - bring the hardware into a known good state
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
 * This function boots the hardware and enables some settings that
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
 * require a configuration cycle of the hardware - those cannot be
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
 * set/changed during runtime. After reset the device needs to be
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
 * properly configured for Rx, Tx etc.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
void e1000e_reset(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	struct e1000_mac_info *mac = &adapter->hw.mac;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	struct e1000_fc_info *fc = &adapter->hw.fc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	u32 tx_space, min_tx_space, min_rx_space;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	u32 pba = adapter->pba;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	u16 hwm;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	/* reset Packet Buffer Allocation to default */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	ew32(PBA, pba);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
		 * To maintain wire speed transmits, the Tx FIFO should be
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
		 * large enough to accommodate two full transmit packets,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
		 * the Rx FIFO should be large enough to accommodate at least
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
		 * one full receive packet and is similarly rounded up and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
		 * expressed in KB.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
		pba = er32(PBA);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
		/* upper 16 bits has Tx packet buffer allocation size in KB */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
		tx_space = pba >> 16;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
		/* lower 16 bits has Rx packet buffer allocation size in KB */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
		pba &= 0xffff;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
		 * the Tx fifo also stores 16 bytes of information about the Tx
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
		 * but don't include ethernet FCS because hardware appends it
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
		min_tx_space = (adapter->max_frame_size +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
				sizeof(struct e1000_tx_desc) -
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
				ETH_FCS_LEN) * 2;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
		min_tx_space = ALIGN(min_tx_space, 1024);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		min_tx_space >>= 10;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		/* software strips receive CRC, so leave room for it */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
		min_rx_space = adapter->max_frame_size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
		min_rx_space = ALIGN(min_rx_space, 1024);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
		min_rx_space >>= 10;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		 * If current Tx allocation is less than the min Tx FIFO size,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
		 * and the min Tx FIFO size is less than the current Rx FIFO
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
		 * allocation, take space away from current Rx allocation
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
		if ((tx_space < min_tx_space) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
		    ((min_tx_space - tx_space) < pba)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
			pba -= min_tx_space - tx_space;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
			 * if short on Rx space, Rx wins and must trump Tx
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
			 * adjustment or use Early Receive if available
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
			if (pba < min_rx_space)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
				pba = min_rx_space;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
		ew32(PBA, pba);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
	 * flow control settings
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
	 * The high water mark must be low enough to fit one full frame
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	 * (or the size used for early receive) above it in the Rx FIFO.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	 * Set it to the lower of:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	 * - 90% of the Rx FIFO size, and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	 * - the full Rx FIFO size minus one full frame
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
		fc->pause_time = 0xFFFF;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		fc->pause_time = E1000_FC_PAUSE_TIME;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	fc->send_xon = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	fc->current_mode = fc->requested_mode;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	switch (hw->mac.type) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	case e1000_ich9lan:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	case e1000_ich10lan:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
			pba = 14;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
			ew32(PBA, pba);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
			fc->high_water = 0x2800;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
			fc->low_water = fc->high_water - 8;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
		/* fall-through */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
		hwm = min(((pba << 10) * 9 / 10),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
			  ((pba << 10) - adapter->max_frame_size));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
		fc->low_water = fc->high_water - 8;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	case e1000_pchlan:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
		 * Workaround PCH LOM adapter hangs with certain network
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
		 * loads.  If hangs persist, try disabling Tx flow control.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
			fc->high_water = 0x3500;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
			fc->low_water  = 0x1500;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
			fc->high_water = 0x5000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
			fc->low_water  = 0x3000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
		fc->refresh_time = 0x1000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	case e1000_pch2lan:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
		fc->high_water = 0x05C20;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
		fc->low_water = 0x05048;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
		fc->pause_time = 0x0650;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
		fc->refresh_time = 0x0400;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
			pba = 14;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
			ew32(PBA, pba);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	 * Disable Adaptive Interrupt Moderation if 2 full packets cannot
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	 * fit in receive buffer.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	if (adapter->itr_setting & 0x3) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
		if ((adapter->max_frame_size * 2) > (pba << 10)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
			if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
				dev_info(&adapter->pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
					"Interrupt Throttle Rate turned off\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
				adapter->flags2 |= FLAG2_DISABLE_AIM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
				ew32(ITR, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
		} else if (adapter->flags2 & FLAG2_DISABLE_AIM) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
			dev_info(&adapter->pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
				 "Interrupt Throttle Rate turned on\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
			adapter->flags2 &= ~FLAG2_DISABLE_AIM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
			adapter->itr = 20000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
			ew32(ITR, 1000000000 / (adapter->itr * 256));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	/* Allow time for pending master requests to run */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	mac->ops.reset_hw(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	 * For parts with AMT enabled, let the firmware know
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	 * that the network interface is in control
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
	if (adapter->flags & FLAG_HAS_AMT)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
		e1000e_get_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
	ew32(WUC, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	if (mac->ops.init_hw(hw))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
		e_err("Hardware Error\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	e1000_update_mng_vlan(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	ew32(VET, ETH_P_8021Q);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
	e1000e_reset_adaptive(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
	if (!netif_running(adapter->netdev) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
	    !test_bit(__E1000_TESTING, &adapter->state)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
		e1000_power_down_phy(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
	e1000_get_phy_info(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
		u16 phy_data = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
		 * speed up time to link by disabling smart power down, ignore
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
		 * the return value of this function because there is nothing
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		 * different we would do if it failed
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		phy_data &= ~IGP02E1000_PM_SPD;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
int e1000e_up(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	/* hardware has been reset, we need to reload some things */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	e1000_configure(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	clear_bit(__E1000_DOWN, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	if (adapter->msix_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		e1000_configure_msix(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	e1000_irq_enable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	netif_start_queue(adapter->netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	/* fire a link change interrupt to start the watchdog */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	if (adapter->msix_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
		ew32(ICS, E1000_ICS_LSC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
static void e1000e_flush_descriptors(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	if (!(adapter->flags2 & FLAG2_DMA_BURST))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	/* flush pending descriptor writebacks to memory */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	/* execute the writes immediately */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	 * due to rare timing issues, write to TIDV/RDTR again to ensure the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	 * write is successful
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
	/* execute the writes immediately */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
static void e1000e_update_stats(struct e1000_adapter *adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
void e1000e_down(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
	u32 tctl, rctl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	 * signal that we're down so the interrupt handler does not
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	 * reschedule our watchdog timer
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	set_bit(__E1000_DOWN, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	/* disable receives in the hardware */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	/* flush and sleep below */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	netif_stop_queue(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	/* disable transmits in the hardware */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	tctl = er32(TCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	tctl &= ~E1000_TCTL_EN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	ew32(TCTL, tctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	/* flush both disables and wait for them to finish */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	usleep_range(10000, 20000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	e1000_irq_disable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	del_timer_sync(&adapter->watchdog_timer);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	del_timer_sync(&adapter->phy_info_timer);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
	netif_carrier_off(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
	spin_lock(&adapter->stats64_lock);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
	e1000e_update_stats(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
	spin_unlock(&adapter->stats64_lock);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
	e1000e_flush_descriptors(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	e1000_clean_tx_ring(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
	e1000_clean_rx_ring(adapter->rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	adapter->link_speed = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	adapter->link_duplex = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	if (!pci_channel_offline(adapter->pdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
		e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	 * TODO: for power management, we could drop the link and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	 * pci_disable_device here.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
void e1000e_reinit_locked(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	might_sleep();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
		usleep_range(1000, 2000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	e1000e_down(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	e1000e_up(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	clear_bit(__E1000_RESETTING, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
 * @adapter: board private structure to initialize
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
 * e1000_sw_init initializes the Adapter private data structure.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
 * Fields are initialized based on PCI device information and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
 * OS network device settings (MTU size).
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	adapter->rx_ps_bsize0 = 128;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	adapter->tx_ring_count = E1000_DEFAULT_TXD;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	adapter->rx_ring_count = E1000_DEFAULT_RXD;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	spin_lock_init(&adapter->stats64_lock);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	e1000e_set_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	if (e1000_alloc_queues(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
		return -ENOMEM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
	/* Explicitly disable IRQ since the NIC can be in any state. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	e1000_irq_disable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	set_bit(__E1000_DOWN, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
 * e1000_intr_msi_test - Interrupt Handler
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
 * @irq: interrupt number
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
 * @data: pointer to a network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
static irqreturn_t e1000_intr_msi_test(int irq, void *data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
	struct net_device *netdev = data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
	u32 icr = er32(ICR);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	e_dbg("icr is %08X\n", icr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	if (icr & E1000_ICR_RXSEQ) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
		wmb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	return IRQ_HANDLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
 * e1000_test_msi_interrupt - Returns 0 for successful test
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
 * @adapter: board private struct
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
 * code flow taken from tg3.c
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	int err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	/* poll_enable hasn't been called yet, so don't need disable */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
	/* clear any pending events */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
	er32(ICR);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	/* free the real vector and request a test handler */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
	e1000_free_irq(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
	e1000e_reset_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
	/* Assume that the test fails, if it succeeds then the test
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
	 * MSI irq handler will unset this flag */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
	adapter->flags |= FLAG_MSI_TEST_FAILED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
	err = pci_enable_msi(adapter->pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
		goto msi_test_failed;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
			  netdev->name, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	if (err) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		pci_disable_msi(adapter->pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
		goto msi_test_failed;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
	wmb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	e1000_irq_enable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	/* fire an unusual interrupt on the test handler */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	ew32(ICS, E1000_ICS_RXSEQ);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
	e1e_flush();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	msleep(100);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	e1000_irq_disable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	rmb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		e_info("MSI interrupt test failed, using legacy interrupt.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
		e_dbg("MSI interrupt test succeeded!\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	free_irq(adapter->pdev->irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
	pci_disable_msi(adapter->pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
msi_test_failed:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	e1000e_set_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
	return e1000_request_irq(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
 * @adapter: board private struct
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
 * code flow taken from tg3.c, called with e1000 interrupts disabled.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
static int e1000_test_msi(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	int err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
	u16 pci_cmd;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	if (!(adapter->flags & FLAG_MSI_ENABLED))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
	/* disable SERR in case the MSI write causes a master abort */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
	if (pci_cmd & PCI_COMMAND_SERR)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		pci_write_config_word(adapter->pdev, PCI_COMMAND,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
				      pci_cmd & ~PCI_COMMAND_SERR);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	err = e1000_test_msi_interrupt(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	/* re-enable SERR */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	if (pci_cmd & PCI_COMMAND_SERR) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
		pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
		pci_cmd |= PCI_COMMAND_SERR;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
		pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
 * e1000_open - Called when a network interface is made active
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
 * Returns 0 on success, negative value on failure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
 * The open entry point is called when a network interface is made
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
 * active by the system (IFF_UP).  At this point all resources needed
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
 * for transmit and receive operations are allocated, the interrupt
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
 * handler is registered with the OS, the watchdog timer is started,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
 * and the stack is notified that the interface is ready.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
static int e1000_open(struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	int err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	/* disallow open during test */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
	if (test_bit(__E1000_TESTING, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
		return -EBUSY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
	pm_runtime_get_sync(&pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
	netif_carrier_off(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
	/* allocate transmit descriptors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
	err = e1000e_setup_tx_resources(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
		goto err_setup_tx;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	/* allocate receive descriptors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
	err = e1000e_setup_rx_resources(adapter->rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
		goto err_setup_rx;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	 * If AMT is enabled, let the firmware know that the network
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	 * interface is now open and reset the part to a known state.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
	if (adapter->flags & FLAG_HAS_AMT) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
		e1000e_get_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	e1000e_power_up_phy(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
	if ((adapter->hw.mng_cookie.status &
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
		e1000_update_mng_vlan(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	/* DMA latency requirement to workaround jumbo issue */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
	if (adapter->hw.mac.type == e1000_pch2lan)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
		pm_qos_add_request(&adapter->netdev->pm_qos_req,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
				   PM_QOS_CPU_DMA_LATENCY,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
				   PM_QOS_DEFAULT_VALUE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
	 * before we allocate an interrupt, we must be ready to handle it.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	 * as soon as we call pci_request_irq, so we have to setup our
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	 * clean_rx handler before we do so.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	e1000_configure(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	err = e1000_request_irq(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
		goto err_req_irq;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	 * Work around PCIe errata with MSI interrupts causing some chipsets to
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	 * ignore e1000e MSI messages, which means we need to test our MSI
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	 * interrupt now
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
		err = e1000_test_msi(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		if (err) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
			e_err("Interrupt allocation failed\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
			goto err_req_irq;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	/* From here on the code is the same as e1000e_up() */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
	clear_bit(__E1000_DOWN, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
	napi_enable(&adapter->napi);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
	e1000_irq_enable(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	adapter->tx_hang_recheck = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	netif_start_queue(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
	adapter->idle_check = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	pm_runtime_put(&pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
	/* fire a link status change interrupt to start the watchdog */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	if (adapter->msix_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
		ew32(ICS, E1000_ICS_LSC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
err_req_irq:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
	e1000e_release_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
	e1000_power_down_phy(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	e1000e_free_rx_resources(adapter->rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
err_setup_rx:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
	e1000e_free_tx_resources(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
err_setup_tx:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	pm_runtime_put_sync(&pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
 * e1000_close - Disables a network interface
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
 * Returns 0, this is not allowed to fail
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
 * The close entry point is called when an interface is de-activated
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
 * by the OS.  The hardware is still under the drivers control, but
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
 * needs to be disabled.  A global MAC reset is issued to stop the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
 * hardware, and all transmit and receive resources are freed.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
static int e1000_close(struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	int count = E1000_CHECK_RESET_COUNT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
	while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
		usleep_range(10000, 20000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
	pm_runtime_get_sync(&pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	napi_disable(&adapter->napi);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	if (!test_bit(__E1000_DOWN, &adapter->state)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		e1000e_down(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		e1000_free_irq(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
	e1000_power_down_phy(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	e1000e_free_tx_resources(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
	e1000e_free_rx_resources(adapter->rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
	 * kill manageability vlan ID if supported, but not if a vlan with
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
	 * the same ID is registered on the host OS (let 8021q kill it)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
	if (adapter->hw.mng_cookie.status &
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
	    E1000_MNG_DHCP_COOKIE_STATUS_VLAN)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
	 * If AMT is enabled, let the firmware know that the network
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
	 * interface is now closed
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	if ((adapter->flags & FLAG_HAS_AMT) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
	    !test_bit(__E1000_TESTING, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		e1000e_release_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
	if (adapter->hw.mac.type == e1000_pch2lan)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
		pm_qos_remove_request(&adapter->netdev->pm_qos_req);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
	pm_runtime_put_sync(&pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
 * e1000_set_mac - Change the Ethernet Address of the NIC
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
 * @p: pointer to an address structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
 * Returns 0 on success, negative on failure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
static int e1000_set_mac(struct net_device *netdev, void *p)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
	struct sockaddr *addr = p;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	if (!is_valid_ether_addr(addr->sa_data))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
		return -EADDRNOTAVAIL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
	e1000e_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
		/* activate the work around */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
		e1000e_set_laa_state_82571(&adapter->hw, 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
		 * Hold a copy of the LAA in RAR[14] This is done so that
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
		 * between the time RAR[0] gets clobbered  and the time it
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
		 * of the RARs and no incoming packets directed to this port
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
		 * are dropped. Eventually the LAA will be in RAR[0] and
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
		 * RAR[14]
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
		e1000e_rar_set(&adapter->hw,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
			      adapter->hw.mac.addr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
			      adapter->hw.mac.rar_entry_count - 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
 * e1000e_update_phy_task - work thread to update phy
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
 * @work: pointer to our work struct
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
 * this worker thread exists because we must acquire a
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
 * semaphore to read the phy, which we could msleep while
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
 * waiting for it, and we can't msleep in a timer.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
static void e1000e_update_phy_task(struct work_struct *work)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	struct e1000_adapter *adapter = container_of(work,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
					struct e1000_adapter, update_phy_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	if (test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	e1000_get_phy_info(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
 * Need to wait a few seconds after link up to get diagnostic information from
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
 * the phy
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
static void e1000_update_phy_info(unsigned long data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
	if (test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
	schedule_work(&adapter->update_phy_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
 * e1000e_update_phy_stats - Update the PHY statistics counters
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
 * Read/clear the upper 16-bit PHY registers and read/accumulate lower
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
static void e1000e_update_phy_stats(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	s32 ret_val;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	u16 phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	ret_val = hw->phy.ops.acquire(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	if (ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	 * A page set is expensive so check if already on desired page.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	 * If not, set to the page with the PHY status registers.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	hw->phy.addr = 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
	ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
					   &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	if (ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
		goto release;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	if (phy_data != (HV_STATS_PAGE << IGP_PAGE_SHIFT)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
		ret_val = hw->phy.ops.set_page(hw,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
					       HV_STATS_PAGE << IGP_PAGE_SHIFT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
		if (ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
			goto release;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
	/* Single Collision Count */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
	hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
	ret_val = hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	if (!ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		adapter->stats.scc += phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	/* Excessive Collision Count */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
	ret_val = hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
	if (!ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
		adapter->stats.ecol += phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
	/* Multiple Collision Count */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
	hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
	ret_val = hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
	if (!ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
		adapter->stats.mcc += phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
	/* Late Collision Count */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	ret_val = hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	if (!ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
		adapter->stats.latecol += phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	/* Collision Count - also used for adaptive IFS */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
	hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
	ret_val = hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
	if (!ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		hw->mac.collision_delta = phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
	/* Defer Count */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
	hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
	ret_val = hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	if (!ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
		adapter->stats.dc += phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	/* Transmit with no CRS */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
	hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	ret_val = hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	if (!ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
		adapter->stats.tncrs += phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
release:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
	hw->phy.ops.release(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
 * e1000e_update_stats - Update the board statistics counters
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
static void e1000e_update_stats(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
	 * Prevent stats update while adapter is being reset, or if the pci
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
	 * connection is down.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
	if (adapter->link_speed == 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
	if (pci_channel_offline(pdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
	adapter->stats.crcerrs += er32(CRCERRS);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
	adapter->stats.gprc += er32(GPRC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
	adapter->stats.gorc += er32(GORCL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
	er32(GORCH); /* Clear gorc */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
	adapter->stats.bprc += er32(BPRC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
	adapter->stats.mprc += er32(MPRC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	adapter->stats.roc += er32(ROC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	adapter->stats.mpc += er32(MPC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	/* Half-duplex statistics */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	if (adapter->link_duplex == HALF_DUPLEX) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
		if (adapter->flags2 & FLAG2_HAS_PHY_STATS) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
			e1000e_update_phy_stats(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
			adapter->stats.scc += er32(SCC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
			adapter->stats.ecol += er32(ECOL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
			adapter->stats.mcc += er32(MCC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
			adapter->stats.latecol += er32(LATECOL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
			adapter->stats.dc += er32(DC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
			hw->mac.collision_delta = er32(COLC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
			if ((hw->mac.type != e1000_82574) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
			    (hw->mac.type != e1000_82583))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
				adapter->stats.tncrs += er32(TNCRS);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
		adapter->stats.colc += hw->mac.collision_delta;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
	adapter->stats.xonrxc += er32(XONRXC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
	adapter->stats.xontxc += er32(XONTXC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
	adapter->stats.xoffrxc += er32(XOFFRXC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	adapter->stats.xofftxc += er32(XOFFTXC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
	adapter->stats.gptc += er32(GPTC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	adapter->stats.gotc += er32(GOTCL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	er32(GOTCH); /* Clear gotc */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	adapter->stats.rnbc += er32(RNBC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
	adapter->stats.ruc += er32(RUC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	adapter->stats.mptc += er32(MPTC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	adapter->stats.bptc += er32(BPTC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	/* used for adaptive IFS */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	hw->mac.tx_packet_delta = er32(TPT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	adapter->stats.tpt += hw->mac.tx_packet_delta;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	adapter->stats.algnerrc += er32(ALGNERRC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	adapter->stats.rxerrc += er32(RXERRC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	adapter->stats.cexterr += er32(CEXTERR);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	adapter->stats.tsctc += er32(TSCTC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
	adapter->stats.tsctfc += er32(TSCTFC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	/* Fill out the OS statistics structure */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
	netdev->stats.multicast = adapter->stats.mprc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	netdev->stats.collisions = adapter->stats.colc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	/* Rx Errors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	 * RLEC on some newer hardware can be incorrect so build
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
	 * our own version based on RUC and ROC
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
	netdev->stats.rx_errors = adapter->stats.rxerrc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
		adapter->stats.crcerrs + adapter->stats.algnerrc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
		adapter->stats.ruc + adapter->stats.roc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
		adapter->stats.cexterr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
	netdev->stats.rx_length_errors = adapter->stats.ruc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
					      adapter->stats.roc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
	/* Tx Errors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
	netdev->stats.tx_errors = adapter->stats.ecol +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
				       adapter->stats.latecol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	netdev->stats.tx_window_errors = adapter->stats.latecol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	/* Tx Dropped needs to be maintained elsewhere */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	/* Management Stats */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
	adapter->stats.mgptc += er32(MGTPTC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
	adapter->stats.mgprc += er32(MGTPRC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	adapter->stats.mgpdc += er32(MGTPDC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
 * e1000_phy_read_status - Update the PHY register status snapshot
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
 * @adapter: board private structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
static void e1000_phy_read_status(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	struct e1000_phy_regs *phy = &adapter->phy_regs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
	if ((er32(STATUS) & E1000_STATUS_LU) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		int ret_val;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		ret_val  = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
		ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
		ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
		ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		if (ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
			e_warn("Error reading PHY register\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
		 * Do not read PHY registers if link is not up
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
		 * Set values to typical power-on defaults
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
			     BMSR_ERCAP);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
				  ADVERTISE_ALL | ADVERTISE_CSMA);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		phy->lpa = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
		phy->expansion = EXPANSION_ENABLENPAGE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
		phy->ctrl1000 = ADVERTISE_1000FULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
		phy->stat1000 = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
static void e1000_print_link_info(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	u32 ctrl = er32(CTRL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	/* Link status message must follow this format for user tools */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
	printk(KERN_INFO "e1000e: %s NIC Link is Up %d Mbps %s Duplex, Flow Control: %s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
		adapter->netdev->name,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		adapter->link_speed,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
		(ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE) ? "Rx/Tx" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
		(ctrl & E1000_CTRL_RFCE) ? "Rx" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		(ctrl & E1000_CTRL_TFCE) ? "Tx" : "None");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
static bool e1000e_has_link(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
	bool link_active = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
	s32 ret_val = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	 * get_link_status is set on LSC (link status) interrupt or
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	 * Rx sequence error interrupt.  get_link_status will stay
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
	 * false until the check_for_link establishes link
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	 * for copper adapters ONLY
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
	switch (hw->phy.media_type) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
	case e1000_media_type_copper:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
		if (hw->mac.get_link_status) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
			ret_val = hw->mac.ops.check_for_link(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
			link_active = !hw->mac.get_link_status;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
			link_active = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
	case e1000_media_type_fiber:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		ret_val = hw->mac.ops.check_for_link(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
	case e1000_media_type_internal_serdes:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
		ret_val = hw->mac.ops.check_for_link(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
		link_active = adapter->hw.mac.serdes_has_link;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	case e1000_media_type_unknown:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
		e_info("Gigabit has been disabled, downgrading speed\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
	return link_active;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
static void e1000e_enable_receives(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	/* make sure the receive unit is started */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	    (adapter->flags & FLAG_RX_RESTART_NOW)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
		u32 rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
		ew32(RCTL, rctl | E1000_RCTL_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		adapter->flags &= ~FLAG_RX_RESTART_NOW;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
	 * With 82574 controllers, PHY needs to be checked periodically
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	 * for hung state and reset, if two calls return true
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
	if (e1000_check_phy_82574(hw))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
		adapter->phy_hang_count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		adapter->phy_hang_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	if (adapter->phy_hang_count > 1) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
		adapter->phy_hang_count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
		schedule_work(&adapter->reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
 * e1000_watchdog - Timer Call-back
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
 * @data: pointer to adapter cast into an unsigned long
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
static void e1000_watchdog(unsigned long data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	/* Do the rest outside of interrupt context */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
	schedule_work(&adapter->watchdog_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	/* TODO: make this use queue_delayed_work() */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
static void e1000_watchdog_task(struct work_struct *work)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	struct e1000_adapter *adapter = container_of(work,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
					struct e1000_adapter, watchdog_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	struct e1000_mac_info *mac = &adapter->hw.mac;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
	struct e1000_phy_info *phy = &adapter->hw.phy;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	struct e1000_ring *tx_ring = adapter->tx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	u32 link, tctl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	if (test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	link = e1000e_has_link(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	if ((netif_carrier_ok(netdev)) && link) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
		/* Cancel scheduled suspend requests. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		pm_runtime_resume(netdev->dev.parent);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
		e1000e_enable_receives(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
		goto link_up;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		e1000_update_mng_vlan(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
	if (link) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
		if (!netif_carrier_ok(netdev)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
			bool txb2b = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
			/* Cancel scheduled suspend requests. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
			pm_runtime_resume(netdev->dev.parent);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
			/* update snapshot of PHY registers on LSC */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
			e1000_phy_read_status(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
			mac->ops.get_link_up_info(&adapter->hw,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
						   &adapter->link_speed,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
						   &adapter->link_duplex);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
			e1000_print_link_info(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
			 * On supported PHYs, check for duplex mismatch only
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
			 * if link has autonegotiated at 10/100 half
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
			if ((hw->phy.type == e1000_phy_igp_3 ||
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
			     hw->phy.type == e1000_phy_bm) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
			    (hw->mac.autoneg == true) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
			    (adapter->link_speed == SPEED_10 ||
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
			     adapter->link_speed == SPEED_100) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
			    (adapter->link_duplex == HALF_DUPLEX)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
				u16 autoneg_exp;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
				e1e_rphy(hw, PHY_AUTONEG_EXP, &autoneg_exp);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
				if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
					e_info("Autonegotiated half duplex but link partner cannot autoneg.  Try forcing full duplex if link gets many collisions.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
			/* adjust timeout factor according to speed/duplex */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
			adapter->tx_timeout_factor = 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
			switch (adapter->link_speed) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
			case SPEED_10:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
				txb2b = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
				adapter->tx_timeout_factor = 16;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
				break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
			case SPEED_100:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
				txb2b = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
				adapter->tx_timeout_factor = 10;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
				break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
			 * workaround: re-program speed mode bit after
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
			 * link-up event
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
			    !txb2b) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
				u32 tarc0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
				tarc0 = er32(TARC(0));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
				tarc0 &= ~SPEED_MODE_BIT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
				ew32(TARC(0), tarc0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
			 * disable TSO for pcie and 10/100 speeds, to avoid
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
			 * some hardware issues
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
				switch (adapter->link_speed) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
				case SPEED_10:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
				case SPEED_100:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
					e_info("10/100 speed: disabling TSO\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
					netdev->features &= ~NETIF_F_TSO;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
					netdev->features &= ~NETIF_F_TSO6;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
					break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
				case SPEED_1000:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
					netdev->features |= NETIF_F_TSO;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
					netdev->features |= NETIF_F_TSO6;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
					break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
				default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
					/* oops */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
					break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
				}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
			/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
			 * enable transmits in the hardware, need to do this
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
			 * after setting TARC(0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
			tctl = er32(TCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
			tctl |= E1000_TCTL_EN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
			ew32(TCTL, tctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
                        /*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			 * Perform any post-link-up configuration before
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
			 * reporting link up.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
			if (phy->ops.cfg_on_link_up)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
				phy->ops.cfg_on_link_up(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
			netif_carrier_on(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
			if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
				mod_timer(&adapter->phy_info_timer,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
					  round_jiffies(jiffies + 2 * HZ));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
		if (netif_carrier_ok(netdev)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
			adapter->link_speed = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
			adapter->link_duplex = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
			/* Link status message must follow this format */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
			printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
			       adapter->netdev->name);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
			netif_carrier_off(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
			if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
				mod_timer(&adapter->phy_info_timer,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
					  round_jiffies(jiffies + 2 * HZ));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
			if (adapter->flags & FLAG_RX_NEEDS_RESTART)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
				schedule_work(&adapter->reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
				pm_schedule_suspend(netdev->dev.parent,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
							LINK_TIMEOUT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
link_up:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	spin_lock(&adapter->stats64_lock);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	e1000e_update_stats(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	adapter->tpt_old = adapter->stats.tpt;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	adapter->colc_old = adapter->stats.colc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
	adapter->gorc_old = adapter->stats.gorc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	adapter->gotc_old = adapter->stats.gotc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
	spin_unlock(&adapter->stats64_lock);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	e1000e_update_adaptive(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	if (!netif_carrier_ok(netdev) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	    (e1000_desc_unused(tx_ring) + 1 < tx_ring->count)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
		 * We've lost link, so the controller stops DMA,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
		 * but we've got queued Tx work that's never going
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		 * to get done, so reset controller to flush Tx.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		 * (Do the reset outside of interrupt context).
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		schedule_work(&adapter->reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		/* return immediately since reset is imminent */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
	/* Simple mode for Interrupt Throttle Rate (ITR) */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	if (adapter->itr_setting == 4) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
		 * Total asymmetrical Tx or Rx gets ITR=8000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
		 * everyone else is between 2000-8000.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
		u32 goc = (adapter->gotc + adapter->gorc) / 10000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		u32 dif = (adapter->gotc > adapter->gorc ?
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
			    adapter->gotc - adapter->gorc :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
			    adapter->gorc - adapter->gotc) / 10000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
		ew32(ITR, 1000000000 / (itr * 256));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	/* Cause software interrupt to ensure Rx ring is cleaned */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	if (adapter->msix_entries)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
		ew32(ICS, adapter->rx_ring->ims_val);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		ew32(ICS, E1000_ICS_RXDMT0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	/* flush pending descriptors to memory before detecting Tx hang */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
	e1000e_flush_descriptors(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	/* Force detection of hung controller every watchdog period */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	adapter->detect_tx_hung = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	 * With 82571 controllers, LAA may be overwritten due to controller
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	 * reset from the other port. Set the appropriate LAA in RAR[0]
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
	if (e1000e_get_laa_state_82571(hw))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
		e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	if (adapter->flags2 & FLAG2_CHECK_PHY_HANG)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
		e1000e_check_82574_phy_workaround(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
	/* Reset the timer */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	if (!test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
		mod_timer(&adapter->watchdog_timer,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
			  round_jiffies(jiffies + 2 * HZ));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
#define E1000_TX_FLAGS_CSUM		0x00000001
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
#define E1000_TX_FLAGS_VLAN		0x00000002
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
#define E1000_TX_FLAGS_TSO		0x00000004
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
#define E1000_TX_FLAGS_IPV4		0x00000008
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
#define E1000_TX_FLAGS_NO_FCS		0x00000010
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
#define E1000_TX_FLAGS_VLAN_SHIFT	16
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	struct e1000_context_desc *context_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
	u32 cmd_length = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
	u16 ipcse = 0, tucse, mss;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
	if (!skb_is_gso(skb))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
	if (skb_header_cloned(skb)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
		int err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
		if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
			return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	mss = skb_shinfo(skb)->gso_size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	if (skb->protocol == htons(ETH_P_IP)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
		struct iphdr *iph = ip_hdr(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
		iph->tot_len = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
		iph->check = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		                                         0, IPPROTO_TCP, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
		cmd_length = E1000_TXD_CMD_IP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		ipcse = skb_transport_offset(skb) - 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
	} else if (skb_is_gso_v6(skb)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
		ipv6_hdr(skb)->payload_len = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
		                                       &ipv6_hdr(skb)->daddr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
		                                       0, IPPROTO_TCP, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		ipcse = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
	ipcss = skb_network_offset(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
	tucss = skb_transport_offset(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	tucse = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
	               E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	i = tx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
	buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
	context_desc->lower_setup.ip_fields.ipcss  = ipcss;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	context_desc->lower_setup.ip_fields.ipcso  = ipcso;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	context_desc->upper_setup.tcp_fields.tucss = tucss;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
	context_desc->upper_setup.tcp_fields.tucso = tucso;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
	context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
	buffer_info->time_stamp = jiffies;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	buffer_info->next_to_watch = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
	if (i == tx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
		i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
	tx_ring->next_to_use = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	return 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	struct e1000_context_desc *context_desc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	u8 css;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	u32 cmd_len = E1000_TXD_CMD_DEXT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	__be16 protocol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	if (skb->ip_summed != CHECKSUM_PARTIAL)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
		protocol = skb->protocol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	switch (protocol) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
	case cpu_to_be16(ETH_P_IP):
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
			cmd_len |= E1000_TXD_CMD_TCP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	case cpu_to_be16(ETH_P_IPV6):
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
		/* XXX not handling all IPV6 headers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
			cmd_len |= E1000_TXD_CMD_TCP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
		if (unlikely(net_ratelimit()))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
			e_warn("checksum_partial proto=%x!\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
			       be16_to_cpu(protocol));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	css = skb_checksum_start_offset(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	i = tx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	context_desc->lower_setup.ip_config = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	context_desc->upper_setup.tcp_fields.tucss = css;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	context_desc->upper_setup.tcp_fields.tucso =
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
				css + skb->csum_offset;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	context_desc->upper_setup.tcp_fields.tucse = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	context_desc->tcp_seg_setup.data = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
	buffer_info->time_stamp = jiffies;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	buffer_info->next_to_watch = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	if (i == tx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
		i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	tx_ring->next_to_use = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	return 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
#define E1000_MAX_PER_TXD	8192
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
#define E1000_MAX_TXD_PWR	12
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
			unsigned int first, unsigned int max_per_txd,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
			unsigned int nr_frags, unsigned int mss)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
	struct pci_dev *pdev = adapter->pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	unsigned int len = skb_headlen(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	unsigned int offset = 0, size, count = 0, i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	unsigned int f, bytecount, segs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	i = tx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
	while (len) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
		buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
		size = min(len, max_per_txd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
		buffer_info->length = size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		buffer_info->time_stamp = jiffies;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
		buffer_info->next_to_watch = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
		buffer_info->dma = dma_map_single(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
						  skb->data + offset,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
						  size, DMA_TO_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
		buffer_info->mapped_as_page = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
			goto dma_error;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
		len -= size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
		offset += size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
		count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
		if (len) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
			i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
			if (i == tx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
				i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	for (f = 0; f < nr_frags; f++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
		const struct skb_frag_struct *frag;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
		frag = &skb_shinfo(skb)->frags[f];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
		len = skb_frag_size(frag);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
		offset = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
		while (len) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
			i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
			if (i == tx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
				i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
			buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
			size = min(len, max_per_txd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
			buffer_info->length = size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
			buffer_info->time_stamp = jiffies;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
			buffer_info->next_to_watch = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
						offset, size, DMA_TO_DEVICE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
			buffer_info->mapped_as_page = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
				goto dma_error;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
			len -= size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
			offset += size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
			count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
	segs = skb_shinfo(skb)->gso_segs ? : 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
	/* multiply data chunks by size of headers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
	tx_ring->buffer_info[i].skb = skb;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
	tx_ring->buffer_info[i].segs = segs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
	tx_ring->buffer_info[i].bytecount = bytecount;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
	tx_ring->buffer_info[first].next_to_watch = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	return count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
dma_error:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	dev_err(&pdev->dev, "Tx DMA map failed\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	buffer_info->dma = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	if (count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
		count--;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
	while (count--) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
		if (i == 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
			i += tx_ring->count;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
		i--;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
		e1000_put_txbuf(tx_ring, buffer_info);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
	struct e1000_tx_desc *tx_desc = NULL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
	struct e1000_buffer *buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
	unsigned int i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
	if (tx_flags & E1000_TX_FLAGS_TSO) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
			     E1000_TXD_CMD_TSE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
		if (tx_flags & E1000_TX_FLAGS_IPV4)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
		txd_lower |= E1000_TXD_CMD_VLE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
		txd_lower &= ~(E1000_TXD_CMD_IFCS);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
	i = tx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
	do {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
		buffer_info = &tx_ring->buffer_info[i];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
		tx_desc = E1000_TX_DESC(*tx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
		tx_desc->lower.data =
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
			cpu_to_le32(txd_lower | buffer_info->length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
		tx_desc->upper.data = cpu_to_le32(txd_upper);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
		i++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
		if (i == tx_ring->count)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
			i = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
	} while (--count > 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	 * Force memory writes to complete before letting h/w
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
	 * know there are new descriptors to fetch.  (Only
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
	 * applicable for weak-ordered memory model archs,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
	 * such as IA-64).
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
	wmb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	tx_ring->next_to_use = i;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
		e1000e_update_tdt_wa(tx_ring, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
		writel(i, tx_ring->tail);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	 * we need this if more than one processor can write to our tail
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	 * at a time, it synchronizes IO on IA64/Altix systems
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	mmiowb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
#define MINIMUM_DHCP_PACKET_SIZE 282
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
				    struct sk_buff *skb)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	struct e1000_hw *hw =  &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
	u16 length, offset;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	if (vlan_tx_tag_present(skb)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
		    (adapter->hw.mng_cookie.status &
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
			return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
	if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
	{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
		const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
		struct udphdr *udp;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
		if (ip->protocol != IPPROTO_UDP)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
			return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
		if (ntohs(udp->dest) != 67)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
			return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
		offset = (u8 *)udp + 8 - skb->data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		length = skb->len - offset;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
		return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	struct e1000_adapter *adapter = tx_ring->adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
	netif_stop_queue(adapter->netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
	 * Herbert's original patch had:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
	 *  smp_mb__after_netif_stop_queue();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
	 * but since that doesn't exist yet, just open code it.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
	smp_mb();
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
	 * We need to check again in a case another CPU has just
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
	 * made room available.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
	if (e1000_desc_unused(tx_ring) < size)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
		return -EBUSY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	/* A reprieve! */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
	netif_start_queue(adapter->netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
	++adapter->restart_queue;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
	if (e1000_desc_unused(tx_ring) >= size)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
	return __e1000_maybe_stop_tx(tx_ring, size);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
				    struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
	struct e1000_ring *tx_ring = adapter->tx_ring;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
	unsigned int first;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
	unsigned int max_per_txd = E1000_MAX_PER_TXD;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
	unsigned int tx_flags = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
	unsigned int len = skb_headlen(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
	unsigned int nr_frags;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	unsigned int mss;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
	int count = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
	int tso;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
	unsigned int f;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
	if (test_bit(__E1000_DOWN, &adapter->state)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
		dev_kfree_skb_any(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
		return NETDEV_TX_OK;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
	if (skb->len <= 0) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
		dev_kfree_skb_any(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
		return NETDEV_TX_OK;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
	mss = skb_shinfo(skb)->gso_size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
	 * The controller does a simple calculation to
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
	 * make sure there is enough room in the FIFO before
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
	 * initiating the DMA for each buffer.  The calc is:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	 * 4 = ceil(buffer len/mss).  To make sure we don't
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	 * overrun the FIFO, adjust the max buffer len if mss
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	 * drops.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	if (mss) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
		u8 hdr_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
		max_per_txd = min(mss << 2, max_per_txd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
		max_txd_pwr = fls(max_per_txd) - 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
		 * TSO Workaround for 82571/2/3 Controllers -- if skb->data
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
		 * points to just header, pull a few bytes of payload from
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
		 * frags into skb->data
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
		/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
		 * we do this workaround for ES2LAN, but it is un-necessary,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
		 * avoiding it could save a lot of cycles
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
		 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
		if (skb->data_len && (hdr_len == len)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
			unsigned int pull_size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
			pull_size = min_t(unsigned int, 4, skb->data_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
			if (!__pskb_pull_tail(skb, pull_size)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
				e_err("__pskb_pull_tail failed.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
				dev_kfree_skb_any(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
				return NETDEV_TX_OK;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
			len = skb_headlen(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
	/* reserve a descriptor for the offload context */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
		count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
	count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	count += TXD_USE_COUNT(len, max_txd_pwr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
	nr_frags = skb_shinfo(skb)->nr_frags;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
	for (f = 0; f < nr_frags; f++)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
		count += TXD_USE_COUNT(skb_frag_size(&skb_shinfo(skb)->frags[f]),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
				       max_txd_pwr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
	if (adapter->hw.mac.tx_pkt_filtering)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
		e1000_transfer_dhcp_info(adapter, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
	 * need: count + 2 desc gap to keep tail from touching
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
	 * head, otherwise try next time
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
	if (e1000_maybe_stop_tx(tx_ring, count + 2))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		return NETDEV_TX_BUSY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	if (vlan_tx_tag_present(skb)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
		tx_flags |= E1000_TX_FLAGS_VLAN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
	first = tx_ring->next_to_use;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	tso = e1000_tso(tx_ring, skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	if (tso < 0) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
		dev_kfree_skb_any(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
		return NETDEV_TX_OK;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	if (tso)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
		tx_flags |= E1000_TX_FLAGS_TSO;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	else if (e1000_tx_csum(tx_ring, skb))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
		tx_flags |= E1000_TX_FLAGS_CSUM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	 * Old method was to assume IPv4 packet by default if TSO was enabled.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
	 * no longer assume, we must.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
	if (skb->protocol == htons(ETH_P_IP))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
		tx_flags |= E1000_TX_FLAGS_IPV4;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
	if (unlikely(skb->no_fcs))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
		tx_flags |= E1000_TX_FLAGS_NO_FCS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	/* if count is 0 then mapping error has occurred */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
	count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
	if (count) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
		netdev_sent_queue(netdev, skb->len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
		e1000_tx_queue(tx_ring, tx_flags, count);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
		/* Make sure there is space in the ring for the next send. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
		e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
		dev_kfree_skb_any(skb);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
		tx_ring->buffer_info[first].time_stamp = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
		tx_ring->next_to_use = first;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
	return NETDEV_TX_OK;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
 * e1000_tx_timeout - Respond to a Tx Hang
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
static void e1000_tx_timeout(struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
	/* Do the reset outside of interrupt context */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
	adapter->tx_timeout_count++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
	schedule_work(&adapter->reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
static void e1000_reset_task(struct work_struct *work)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
	struct e1000_adapter *adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
	adapter = container_of(work, struct e1000_adapter, reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
	/* don't run the task if already down */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
	if (test_bit(__E1000_DOWN, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
	if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
	      (adapter->flags & FLAG_RX_RESTART_NOW))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
		e1000e_dump(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
		e_err("Reset adapter\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
	e1000e_reinit_locked(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
 * e1000_get_stats64 - Get System Network Statistics
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
 * @stats: rtnl_link_stats64 pointer
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
 * Returns the address of the device statistics structure.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
                                             struct rtnl_link_stats64 *stats)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	memset(stats, 0, sizeof(struct rtnl_link_stats64));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
	spin_lock(&adapter->stats64_lock);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
	e1000e_update_stats(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
	/* Fill out the OS statistics structure */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
	stats->rx_bytes = adapter->stats.gorc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
	stats->rx_packets = adapter->stats.gprc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
	stats->tx_bytes = adapter->stats.gotc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
	stats->tx_packets = adapter->stats.gptc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
	stats->multicast = adapter->stats.mprc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
	stats->collisions = adapter->stats.colc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
	/* Rx Errors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
	 * RLEC on some newer hardware can be incorrect so build
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	 * our own version based on RUC and ROC
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
	stats->rx_errors = adapter->stats.rxerrc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
		adapter->stats.crcerrs + adapter->stats.algnerrc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
		adapter->stats.ruc + adapter->stats.roc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
		adapter->stats.cexterr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
	stats->rx_length_errors = adapter->stats.ruc +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
					      adapter->stats.roc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
	stats->rx_crc_errors = adapter->stats.crcerrs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
	stats->rx_frame_errors = adapter->stats.algnerrc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	stats->rx_missed_errors = adapter->stats.mpc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
	/* Tx Errors */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
	stats->tx_errors = adapter->stats.ecol +
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
				       adapter->stats.latecol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	stats->tx_aborted_errors = adapter->stats.ecol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
	stats->tx_window_errors = adapter->stats.latecol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
	stats->tx_carrier_errors = adapter->stats.tncrs;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
	/* Tx Dropped needs to be maintained elsewhere */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
	spin_unlock(&adapter->stats64_lock);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
	return stats;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
 * e1000_change_mtu - Change the Maximum Transfer Unit
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
 * @netdev: network interface device structure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
 * @new_mtu: new value for maximum frame size
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
 * Returns 0 on success, negative on failure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
	/* Jumbo frame support */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
		e_err("Jumbo Frames not supported.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
		return -EINVAL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
	/* Supported frame sizes */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
	    (max_frame > adapter->max_hw_frame_size)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
		e_err("Unsupported MTU setting\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
		return -EINVAL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
	/* Jumbo frame workaround on 82579 requires CRC be stripped */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
	if ((adapter->hw.mac.type == e1000_pch2lan) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
	    !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
	    (new_mtu > ETH_DATA_LEN)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
		e_err("Jumbo Frames not supported on 82579 when CRC stripping is disabled.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
		return -EINVAL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
		usleep_range(1000, 2000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
	adapter->max_frame_size = max_frame;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
	netdev->mtu = new_mtu;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
	if (netif_running(netdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
		e1000e_down(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
	 * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	 * means we reserve 2 more, this pushes us to allocate from the next
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
	 * larger slab size.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	 * i.e. RXBUFFER_2048 --> size-4096 slab
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
	 * However with the new *_jumbo_rx* routines, jumbo receives will use
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	 * fragmented skbs
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
	if (max_frame <= 2048)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
		adapter->rx_buffer_len = 2048;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
		adapter->rx_buffer_len = 4096;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
	/* adjust allocation if LPE protects us, and we aren't using SBP */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
	     (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
					 + ETH_FCS_LEN;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
	if (netif_running(netdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
		e1000e_up(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
		e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
	clear_bit(__E1000_RESETTING, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
			   int cmd)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
	struct mii_ioctl_data *data = if_mii(ifr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
	if (adapter->hw.phy.media_type != e1000_media_type_copper)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
		return -EOPNOTSUPP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
	switch (cmd) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
	case SIOCGMIIPHY:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
		data->phy_id = adapter->hw.phy.addr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
	case SIOCGMIIREG:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
		e1000_phy_read_status(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
		switch (data->reg_num & 0x1F) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
		case MII_BMCR:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
			data->val_out = adapter->phy_regs.bmcr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
		case MII_BMSR:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
			data->val_out = adapter->phy_regs.bmsr;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
		case MII_PHYSID1:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
			data->val_out = (adapter->hw.phy.id >> 16);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
		case MII_PHYSID2:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
			data->val_out = (adapter->hw.phy.id & 0xFFFF);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
		case MII_ADVERTISE:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
			data->val_out = adapter->phy_regs.advertise;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
		case MII_LPA:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
			data->val_out = adapter->phy_regs.lpa;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
		case MII_EXPANSION:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
			data->val_out = adapter->phy_regs.expansion;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
		case MII_CTRL1000:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
			data->val_out = adapter->phy_regs.ctrl1000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
		case MII_STAT1000:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
			data->val_out = adapter->phy_regs.stat1000;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
		case MII_ESTATUS:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
			data->val_out = adapter->phy_regs.estatus;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
		default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
			return -EIO;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
	case SIOCSMIIREG:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
		return -EOPNOTSUPP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	switch (cmd) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
	case SIOCGMIIPHY:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
	case SIOCGMIIREG:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
	case SIOCSMIIREG:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
		return e1000_mii_ioctl(netdev, ifr, cmd);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
	default:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
		return -EOPNOTSUPP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
	u32 i, mac_reg;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
	u16 phy_reg, wuc_enable;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
	int retval = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
	/* copy MAC RARs to PHY RARs */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
	e1000_copy_rx_addrs_to_phy_ich8lan(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
	retval = hw->phy.ops.acquire(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
	if (retval) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
		e_err("Could not acquire PHY\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
		return retval;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
	/* Enable access to wakeup registers on and set page to BM_WUC_PAGE */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
	retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
	if (retval)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
		goto release;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
	/* copy MAC MTA to PHY MTA - only needed for pchlan */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
		mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
		hw->phy.ops.write_reg_page(hw, BM_MTA(i),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
					   (u16)(mac_reg & 0xFFFF));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
		hw->phy.ops.write_reg_page(hw, BM_MTA(i) + 1,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
					   (u16)((mac_reg >> 16) & 0xFFFF));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
	/* configure PHY Rx Control register */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
	hw->phy.ops.read_reg_page(&adapter->hw, BM_RCTL, &phy_reg);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
	mac_reg = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
	if (mac_reg & E1000_RCTL_UPE)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
		phy_reg |= BM_RCTL_UPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
	if (mac_reg & E1000_RCTL_MPE)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
		phy_reg |= BM_RCTL_MPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
	phy_reg &= ~(BM_RCTL_MO_MASK);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
	if (mac_reg & E1000_RCTL_MO_3)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
		phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
				<< BM_RCTL_MO_SHIFT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
	if (mac_reg & E1000_RCTL_BAM)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
		phy_reg |= BM_RCTL_BAM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
	if (mac_reg & E1000_RCTL_PMCF)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
		phy_reg |= BM_RCTL_PMCF;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
	mac_reg = er32(CTRL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
	if (mac_reg & E1000_CTRL_RFCE)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
		phy_reg |= BM_RCTL_RFCE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
	hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
	/* enable PHY wakeup in MAC register */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
	ew32(WUFC, wufc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
	ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
	/* configure and enable PHY wakeup in PHY registers */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	/* activate PHY wakeup */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
	wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
	retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
	if (retval)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
		e_err("Could not set PHY Host Wakeup bit\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
release:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
	hw->phy.ops.release(hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
	return retval;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
			    bool runtime)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
	u32 ctrl, ctrl_ext, rctl, status;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	/* Runtime suspend should only enable wakeup for link changes */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
	u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
	int retval = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	netif_device_detach(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
	if (netif_running(netdev)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
		int count = E1000_CHECK_RESET_COUNT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
		while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
			usleep_range(10000, 20000);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
		e1000e_down(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
		e1000_free_irq(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
	e1000e_reset_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
	retval = pci_save_state(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
	if (retval)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
		return retval;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
	status = er32(STATUS);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
	if (status & E1000_STATUS_LU)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
		wufc &= ~E1000_WUFC_LNKC;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
	if (wufc) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
		e1000_setup_rctl(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
		e1000e_set_rx_mode(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
		/* turn on all-multi mode if wake on multicast is enabled */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
		if (wufc & E1000_WUFC_MC) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
			rctl = er32(RCTL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
			rctl |= E1000_RCTL_MPE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
			ew32(RCTL, rctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
		ctrl = er32(CTRL);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
		/* advertise wake from D3Cold */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
		#define E1000_CTRL_ADVD3WUC 0x00100000
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
		/* phy power management enable */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
		#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
		ctrl |= E1000_CTRL_ADVD3WUC;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
		ew32(CTRL, ctrl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
		    adapter->hw.phy.media_type ==
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
		    e1000_media_type_internal_serdes) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
			/* keep the laser running in D3 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
			ctrl_ext = er32(CTRL_EXT);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
			ew32(CTRL_EXT, ctrl_ext);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
		if (adapter->flags & FLAG_IS_ICH)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
			e1000_suspend_workarounds_ich8lan(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
		/* Allow time for pending master requests to run */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
		e1000e_disable_pcie_master(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
			/* enable wakeup by the PHY */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
			retval = e1000_init_phy_wakeup(adapter, wufc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
			if (retval)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
				return retval;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
			/* enable wakeup by the MAC */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
			ew32(WUFC, wufc);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
			ew32(WUC, E1000_WUC_PME_EN);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
		ew32(WUC, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
		ew32(WUFC, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	*enable_wake = !!wufc;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	/* make sure adapter isn't asleep if manageability is enabled */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
	if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
	    (hw->mac.ops.check_mng_mode(hw)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
		*enable_wake = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
	if (adapter->hw.phy.type == e1000_phy_igp_3)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
	 * would have already happened in close and is redundant.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
	e1000e_release_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
	pci_disable_device(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
	if (sleep && wake) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
		pci_prepare_to_sleep(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
	pci_wake_from_d3(pdev, wake);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
	pci_set_power_state(pdev, PCI_D3hot);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
                                    bool wake)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
	 * The pci-e switch on some quad port adapters will report a
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
	 * correctable error when the MAC transitions from D0 to D3.  To
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
	 * prevent this we need to mask off the correctable errors on the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
	 * downstream port of the pci-e switch.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
		struct pci_dev *us_dev = pdev->bus->self;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
		int pos = pci_pcie_cap(us_dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
		u16 devctl;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
		pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
		                      (devctl & ~PCI_EXP_DEVCTL_CERE));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
		e1000_power_off(pdev, sleep, wake);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
		e1000_power_off(pdev, sleep, wake);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
#ifdef CONFIG_PCIEASPM
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
	pci_disable_link_state_locked(pdev, state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
#else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
	int pos;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
	u16 reg16;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
	 * Both device and parent should have the same ASPM setting.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
	 * Disable ASPM in downstream component first and then upstream.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
	pos = pci_pcie_cap(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
	reg16 &= ~state;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
	if (!pdev->bus->self)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
	pos = pci_pcie_cap(pdev->bus->self);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
	pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
	reg16 &= ~state;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
	pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
#endif
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
	dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
		 (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
		 (state & PCIE_LINK_STATE_L1) ? "L1" : "");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
	__e1000e_disable_aspm(pdev, state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
#ifdef CONFIG_PM
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
static bool e1000e_pm_ready(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
	return !!adapter->tx_ring->buffer_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
static int __e1000_resume(struct pci_dev *pdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	u16 aspm_disable_flag = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	u32 err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
	if (aspm_disable_flag)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
		e1000e_disable_aspm(pdev, aspm_disable_flag);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
	pci_set_power_state(pdev, PCI_D0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
	pci_restore_state(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
	pci_save_state(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
	e1000e_set_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
	if (netif_running(netdev)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
		err = e1000_request_irq(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
		if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
			return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
	if (hw->mac.type == e1000_pch2lan)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
		e1000_resume_workarounds_pchlan(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
	e1000e_power_up_phy(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
	/* report the system wakeup cause from S3/S4 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
		u16 phy_data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
		e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
		if (phy_data) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
			e_info("PHY Wakeup cause - %s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
				phy_data & E1000_WUS_EX ? "Unicast Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
				phy_data & E1000_WUS_MC ? "Multicast Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
				phy_data & E1000_WUS_BC ? "Broadcast Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
				phy_data & E1000_WUS_MAG ? "Magic Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
				phy_data & E1000_WUS_LNKC ?
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
				"Link Status Change" : "other");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
		u32 wus = er32(WUS);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
		if (wus) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
			e_info("MAC Wakeup cause - %s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
				wus & E1000_WUS_EX ? "Unicast Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
				wus & E1000_WUS_MC ? "Multicast Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
				wus & E1000_WUS_BC ? "Broadcast Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
				wus & E1000_WUS_MAG ? "Magic Packet" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
				wus & E1000_WUS_LNKC ? "Link Status Change" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
				"other");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
		ew32(WUS, ~0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
	e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
	e1000_init_manageability_pt(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
	if (netif_running(netdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
		e1000e_up(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
	netif_device_attach(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
	 * If the controller has AMT, do not set DRV_LOAD until the interface
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
	 * is up.  For all other cases, let the f/w know that the h/w is now
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
	 * under the control of the driver.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
	if (!(adapter->flags & FLAG_HAS_AMT))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
		e1000e_get_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
#ifdef CONFIG_PM_SLEEP
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
static int e1000_suspend(struct device *dev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
	struct pci_dev *pdev = to_pci_dev(dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
	int retval;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
	bool wake;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
	retval = __e1000_shutdown(pdev, &wake, false);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
	if (!retval)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
		e1000_complete_shutdown(pdev, true, wake);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
	return retval;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
static int e1000_resume(struct device *dev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
	struct pci_dev *pdev = to_pci_dev(dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
	if (e1000e_pm_ready(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
		adapter->idle_check = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
	return __e1000_resume(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
#endif /* CONFIG_PM_SLEEP */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
#ifdef CONFIG_PM_RUNTIME
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
static int e1000_runtime_suspend(struct device *dev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
	struct pci_dev *pdev = to_pci_dev(dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
	if (e1000e_pm_ready(adapter)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
		bool wake;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
		__e1000_shutdown(pdev, &wake, true);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
static int e1000_idle(struct device *dev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
	struct pci_dev *pdev = to_pci_dev(dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
	if (!e1000e_pm_ready(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
	if (adapter->idle_check) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
		adapter->idle_check = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
		if (!e1000e_has_link(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
			pm_schedule_suspend(dev, MSEC_PER_SEC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
	return -EBUSY;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
static int e1000_runtime_resume(struct device *dev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
	struct pci_dev *pdev = to_pci_dev(dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
	if (!e1000e_pm_ready(adapter))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
	adapter->idle_check = !dev->power.runtime_auto;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
	return __e1000_resume(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
#endif /* CONFIG_PM_RUNTIME */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
#endif /* CONFIG_PM */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
static void e1000_shutdown(struct pci_dev *pdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
	bool wake = false;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
	__e1000_shutdown(pdev, &wake, false);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
	if (system_state == SYSTEM_POWER_OFF)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
		e1000_complete_shutdown(pdev, false, wake);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
#ifdef CONFIG_NET_POLL_CONTROLLER
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
static irqreturn_t e1000_intr_msix(int irq, void *data)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
	struct net_device *netdev = data;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
	if (adapter->msix_entries) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
		int vector, msix_irq;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
		vector = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
		msix_irq = adapter->msix_entries[vector].vector;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
		disable_irq(msix_irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
		e1000_intr_msix_rx(msix_irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
		enable_irq(msix_irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
		vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
		msix_irq = adapter->msix_entries[vector].vector;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
		disable_irq(msix_irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
		e1000_intr_msix_tx(msix_irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
		enable_irq(msix_irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
		vector++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
		msix_irq = adapter->msix_entries[vector].vector;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
		disable_irq(msix_irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
		e1000_msix_other(msix_irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
		enable_irq(msix_irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5821
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5822
	return IRQ_HANDLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5823
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5824
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5825
/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5826
 * Polling 'interrupt' - used by things like netconsole to send skbs
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5827
 * without having to re-enable interrupts. It's not called while
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5828
 * the interrupt routine is executing.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5829
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5830
static void e1000_netpoll(struct net_device *netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5831
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5832
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5833
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5834
	switch (adapter->int_mode) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5835
	case E1000E_INT_MODE_MSIX:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5836
		e1000_intr_msix(adapter->pdev->irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5837
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5838
	case E1000E_INT_MODE_MSI:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5839
		disable_irq(adapter->pdev->irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5840
		e1000_intr_msi(adapter->pdev->irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5841
		enable_irq(adapter->pdev->irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5842
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5843
	default: /* E1000E_INT_MODE_LEGACY */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5844
		disable_irq(adapter->pdev->irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5845
		e1000_intr(adapter->pdev->irq, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5846
		enable_irq(adapter->pdev->irq);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5847
		break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5848
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5849
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5850
#endif
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5851
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5852
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5853
 * e1000_io_error_detected - called when PCI error is detected
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5854
 * @pdev: Pointer to PCI device
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5855
 * @state: The current pci connection state
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5856
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5857
 * This function is called after a PCI bus error affecting
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5858
 * this device has been detected.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5859
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5860
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5861
						pci_channel_state_t state)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5862
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5863
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5864
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5865
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5866
	netif_device_detach(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5867
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5868
	if (state == pci_channel_io_perm_failure)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5869
		return PCI_ERS_RESULT_DISCONNECT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5870
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5871
	if (netif_running(netdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5872
		e1000e_down(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5873
	pci_disable_device(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5874
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5875
	/* Request a slot slot reset. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5876
	return PCI_ERS_RESULT_NEED_RESET;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5877
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5878
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5879
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5880
 * e1000_io_slot_reset - called after the pci bus has been reset.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5881
 * @pdev: Pointer to PCI device
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5882
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5883
 * Restart the card from scratch, as if from a cold-boot. Implementation
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5884
 * resembles the first-half of the e1000_resume routine.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5885
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5886
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5887
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5888
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5889
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5890
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5891
	u16 aspm_disable_flag = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5892
	int err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5893
	pci_ers_result_t result;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5894
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5895
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5896
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5897
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5898
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5899
	if (aspm_disable_flag)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5900
		e1000e_disable_aspm(pdev, aspm_disable_flag);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5901
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5902
	err = pci_enable_device_mem(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5903
	if (err) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5904
		dev_err(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5905
			"Cannot re-enable PCI device after reset.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5906
		result = PCI_ERS_RESULT_DISCONNECT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5907
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5908
		pci_set_master(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5909
		pdev->state_saved = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5910
		pci_restore_state(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5911
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5912
		pci_enable_wake(pdev, PCI_D3hot, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5913
		pci_enable_wake(pdev, PCI_D3cold, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5914
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5915
		e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5916
		ew32(WUS, ~0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5917
		result = PCI_ERS_RESULT_RECOVERED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5918
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5919
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5920
	pci_cleanup_aer_uncorrect_error_status(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5921
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5922
	return result;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5923
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5924
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5925
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5926
 * e1000_io_resume - called when traffic can start flowing again.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5927
 * @pdev: Pointer to PCI device
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5928
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5929
 * This callback is called when the error recovery driver tells us that
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5930
 * its OK to resume normal operation. Implementation resembles the
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5931
 * second-half of the e1000_resume routine.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5932
 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5933
static void e1000_io_resume(struct pci_dev *pdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5934
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5935
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5936
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5937
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5938
	e1000_init_manageability_pt(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5939
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5940
	if (netif_running(netdev)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5941
		if (e1000e_up(adapter)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5942
			dev_err(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5943
				"can't bring device back up after reset\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5944
			return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5945
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5946
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5947
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5948
	netif_device_attach(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5949
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5950
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5951
	 * If the controller has AMT, do not set DRV_LOAD until the interface
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5952
	 * is up.  For all other cases, let the f/w know that the h/w is now
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5953
	 * under the control of the driver.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5954
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5955
	if (!(adapter->flags & FLAG_HAS_AMT))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5956
		e1000e_get_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5957
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5958
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5959
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5960
static void e1000_print_device_info(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5961
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5962
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5963
	struct net_device *netdev = adapter->netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5964
	u32 ret_val;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5965
	u8 pba_str[E1000_PBANUM_LENGTH];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5966
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5967
	/* print bus type/speed/width info */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5968
	e_info("(PCI Express:2.5GT/s:%s) %pM\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5969
	       /* bus width */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5970
	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5971
	        "Width x1"),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5972
	       /* MAC address */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5973
	       netdev->dev_addr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5974
	e_info("Intel(R) PRO/%s Network Connection\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5975
	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5976
	ret_val = e1000_read_pba_string_generic(hw, pba_str,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5977
						E1000_PBANUM_LENGTH);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5978
	if (ret_val)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5979
		strlcpy((char *)pba_str, "Unknown", sizeof(pba_str));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5980
	e_info("MAC: %d, PHY: %d, PBA No: %s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5981
	       hw->mac.type, hw->phy.type, pba_str);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5982
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5983
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5984
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5985
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5986
	struct e1000_hw *hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5987
	int ret_val;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5988
	u16 buf = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5989
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5990
	if (hw->mac.type != e1000_82573)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5991
		return;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5992
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5993
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5994
	le16_to_cpus(&buf);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5995
	if (!ret_val && (!(buf & (1 << 0)))) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5996
		/* Deep Smart Power Down (DSPD) */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5997
		dev_warn(&adapter->pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5998
			 "Warning: detected DSPD enabled in EEPROM\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5999
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6000
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6001
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6002
static int e1000_set_features(struct net_device *netdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6003
			      netdev_features_t features)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6004
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6005
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6006
	netdev_features_t changed = features ^ netdev->features;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6007
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6008
	if (changed & (NETIF_F_TSO | NETIF_F_TSO6))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6009
		adapter->flags |= FLAG_TSO_FORCE;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6010
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6011
	if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6012
			 NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6013
			 NETIF_F_RXALL)))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6014
		return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6015
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6016
	if (changed & NETIF_F_RXFCS) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6017
		if (features & NETIF_F_RXFCS) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6018
			adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6019
		} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6020
			/* We need to take it back to defaults, which might mean
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6021
			 * stripping is still disabled at the adapter level.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6022
			 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6023
			if (adapter->flags2 & FLAG2_DFLT_CRC_STRIPPING)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6024
				adapter->flags2 |= FLAG2_CRC_STRIPPING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6025
			else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6026
				adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6027
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6028
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6029
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6030
	netdev->features = features;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6031
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6032
	if (netif_running(netdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6033
		e1000e_reinit_locked(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6034
	else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6035
		e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6036
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6037
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6038
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6039
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6040
static const struct net_device_ops e1000e_netdev_ops = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6041
	.ndo_open		= e1000_open,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6042
	.ndo_stop		= e1000_close,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6043
	.ndo_start_xmit		= e1000_xmit_frame,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6044
	.ndo_get_stats64	= e1000e_get_stats64,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6045
	.ndo_set_rx_mode	= e1000e_set_rx_mode,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6046
	.ndo_set_mac_address	= e1000_set_mac,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6047
	.ndo_change_mtu		= e1000_change_mtu,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6048
	.ndo_do_ioctl		= e1000_ioctl,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6049
	.ndo_tx_timeout		= e1000_tx_timeout,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6050
	.ndo_validate_addr	= eth_validate_addr,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6051
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6052
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6053
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6054
#ifdef CONFIG_NET_POLL_CONTROLLER
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6055
	.ndo_poll_controller	= e1000_netpoll,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6056
#endif
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6057
	.ndo_set_features = e1000_set_features,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6058
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6059
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6060
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6061
 * e1000_probe - Device Initialization Routine
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6062
 * @pdev: PCI device information struct
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6063
 * @ent: entry in e1000_pci_tbl
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6064
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6065
 * Returns 0 on success, negative on failure
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6066
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6067
 * e1000_probe initializes an adapter identified by a pci_dev structure.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6068
 * The OS initialization, configuring of the adapter private structure,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6069
 * and a hardware reset occur.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6070
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6071
static int __devinit e1000_probe(struct pci_dev *pdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6072
				 const struct pci_device_id *ent)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6073
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6074
	struct net_device *netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6075
	struct e1000_adapter *adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6076
	struct e1000_hw *hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6077
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6078
	resource_size_t mmio_start, mmio_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6079
	resource_size_t flash_start, flash_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6080
	static int cards_found;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6081
	u16 aspm_disable_flag = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6082
	int i, err, pci_using_dac;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6083
	u16 eeprom_data = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6084
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6085
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6086
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6087
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6088
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6089
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6090
	if (aspm_disable_flag)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6091
		e1000e_disable_aspm(pdev, aspm_disable_flag);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6092
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6093
	err = pci_enable_device_mem(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6094
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6095
		return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6096
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6097
	pci_using_dac = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6098
	err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6099
	if (!err) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6100
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6101
		if (!err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6102
			pci_using_dac = 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6103
	} else {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6104
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6105
		if (err) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6106
			err = dma_set_coherent_mask(&pdev->dev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6107
						    DMA_BIT_MASK(32));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6108
			if (err) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6109
				dev_err(&pdev->dev, "No usable DMA configuration, aborting\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6110
				goto err_dma;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6111
			}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6112
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6113
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6114
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6115
	err = pci_request_selected_regions_exclusive(pdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6116
	                                  pci_select_bars(pdev, IORESOURCE_MEM),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6117
	                                  e1000e_driver_name);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6118
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6119
		goto err_pci_reg;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6120
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6121
	/* AER (Advanced Error Reporting) hooks */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6122
	pci_enable_pcie_error_reporting(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6123
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6124
	pci_set_master(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6125
	/* PCI config space info */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6126
	err = pci_save_state(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6127
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6128
		goto err_alloc_etherdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6129
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6130
	err = -ENOMEM;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6131
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6132
	if (!netdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6133
		goto err_alloc_etherdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6134
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6135
	SET_NETDEV_DEV(netdev, &pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6136
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6137
	netdev->irq = pdev->irq;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6138
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6139
	pci_set_drvdata(pdev, netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6140
	adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6141
	hw = &adapter->hw;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6142
	adapter->netdev = netdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6143
	adapter->pdev = pdev;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6144
	adapter->ei = ei;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6145
	adapter->pba = ei->pba;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6146
	adapter->flags = ei->flags;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6147
	adapter->flags2 = ei->flags2;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6148
	adapter->hw.adapter = adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6149
	adapter->hw.mac.type = ei->mac;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6150
	adapter->max_hw_frame_size = ei->max_hw_frame_size;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6151
	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6152
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6153
	mmio_start = pci_resource_start(pdev, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6154
	mmio_len = pci_resource_len(pdev, 0);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6155
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6156
	err = -EIO;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6157
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6158
	if (!adapter->hw.hw_addr)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6159
		goto err_ioremap;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6160
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6161
	if ((adapter->flags & FLAG_HAS_FLASH) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6162
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6163
		flash_start = pci_resource_start(pdev, 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6164
		flash_len = pci_resource_len(pdev, 1);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6165
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6166
		if (!adapter->hw.flash_address)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6167
			goto err_flashmap;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6168
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6169
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6170
	/* construct the net_device struct */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6171
	netdev->netdev_ops		= &e1000e_netdev_ops;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6172
	e1000e_set_ethtool_ops(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6173
	netdev->watchdog_timeo		= 5 * HZ;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6174
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6175
	strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6176
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6177
	netdev->mem_start = mmio_start;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6178
	netdev->mem_end = mmio_start + mmio_len;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6179
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6180
	adapter->bd_number = cards_found++;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6181
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6182
	e1000e_check_options(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6183
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6184
	/* setup adapter struct */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6185
	err = e1000_sw_init(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6186
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6187
		goto err_sw_init;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6188
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6189
	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6190
	memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6191
	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6192
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6193
	err = ei->get_variants(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6194
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6195
		goto err_hw_init;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6196
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6197
	if ((adapter->flags & FLAG_IS_ICH) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6198
	    (adapter->flags & FLAG_READ_ONLY_NVM))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6199
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6200
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6201
	hw->mac.ops.get_bus_info(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6202
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6203
	adapter->hw.phy.autoneg_wait_to_complete = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6204
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6205
	/* Copper options */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6206
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6207
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6208
		adapter->hw.phy.disable_polarity_correction = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6209
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6210
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6211
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6212
	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6213
		e_info("PHY reset is blocked due to SOL/IDER session.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6214
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6215
	/* Set initial default active device features */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6216
	netdev->features = (NETIF_F_SG |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6217
			    NETIF_F_HW_VLAN_RX |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6218
			    NETIF_F_HW_VLAN_TX |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6219
			    NETIF_F_TSO |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6220
			    NETIF_F_TSO6 |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6221
			    NETIF_F_RXHASH |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6222
			    NETIF_F_RXCSUM |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6223
			    NETIF_F_HW_CSUM);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6224
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6225
	/* Set user-changeable features (subset of all device features) */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6226
	netdev->hw_features = netdev->features;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6227
	netdev->hw_features |= NETIF_F_RXFCS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6228
	netdev->priv_flags |= IFF_SUPP_NOFCS;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6229
	netdev->hw_features |= NETIF_F_RXALL;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6230
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6231
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6232
		netdev->features |= NETIF_F_HW_VLAN_FILTER;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6233
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6234
	netdev->vlan_features |= (NETIF_F_SG |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6235
				  NETIF_F_TSO |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6236
				  NETIF_F_TSO6 |
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6237
				  NETIF_F_HW_CSUM);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6238
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6239
	netdev->priv_flags |= IFF_UNICAST_FLT;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6240
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6241
	if (pci_using_dac) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6242
		netdev->features |= NETIF_F_HIGHDMA;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6243
		netdev->vlan_features |= NETIF_F_HIGHDMA;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6244
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6245
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6246
	if (e1000e_enable_mng_pass_thru(&adapter->hw))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6247
		adapter->flags |= FLAG_MNG_PT_ENABLED;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6248
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6249
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6250
	 * before reading the NVM, reset the controller to
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6251
	 * put the device in a known good starting state
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6252
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6253
	adapter->hw.mac.ops.reset_hw(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6254
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6255
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6256
	 * systems with ASPM and others may see the checksum fail on the first
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6257
	 * attempt. Let's give it a few tries
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6258
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6259
	for (i = 0;; i++) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6260
		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6261
			break;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6262
		if (i == 2) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6263
			e_err("The NVM Checksum Is Not Valid\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6264
			err = -EIO;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6265
			goto err_eeprom;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6266
		}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6267
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6268
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6269
	e1000_eeprom_checks(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6270
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6271
	/* copy the MAC address */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6272
	if (e1000e_read_mac_addr(&adapter->hw))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6273
		e_err("NVM Read Error while reading MAC address\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6274
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6275
	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6276
	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6277
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6278
	if (!is_valid_ether_addr(netdev->perm_addr)) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6279
		e_err("Invalid MAC Address: %pM\n", netdev->perm_addr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6280
		err = -EIO;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6281
		goto err_eeprom;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6282
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6283
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6284
	init_timer(&adapter->watchdog_timer);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6285
	adapter->watchdog_timer.function = e1000_watchdog;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6286
	adapter->watchdog_timer.data = (unsigned long) adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6287
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6288
	init_timer(&adapter->phy_info_timer);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6289
	adapter->phy_info_timer.function = e1000_update_phy_info;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6290
	adapter->phy_info_timer.data = (unsigned long) adapter;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6291
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6292
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6293
	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6294
	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6295
	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6296
	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6297
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6298
	/* Initialize link parameters. User can change them with ethtool */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6299
	adapter->hw.mac.autoneg = 1;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6300
	adapter->fc_autoneg = true;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6301
	adapter->hw.fc.requested_mode = e1000_fc_default;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6302
	adapter->hw.fc.current_mode = e1000_fc_default;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6303
	adapter->hw.phy.autoneg_advertised = 0x2f;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6304
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6305
	/* ring size defaults */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6306
	adapter->rx_ring->count = 256;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6307
	adapter->tx_ring->count = 256;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6308
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6309
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6310
	 * Initial Wake on LAN setting - If APM wake is enabled in
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6311
	 * the EEPROM, enable the ACPI Magic Packet filter
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6312
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6313
	if (adapter->flags & FLAG_APME_IN_WUC) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6314
		/* APME bit in EEPROM is mapped to WUC.APME */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6315
		eeprom_data = er32(WUC);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6316
		eeprom_apme_mask = E1000_WUC_APME;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6317
		if ((hw->mac.type > e1000_ich10lan) &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6318
		    (eeprom_data & E1000_WUC_PHY_WAKE))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6319
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6320
	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6321
		if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6322
		    (adapter->hw.bus.func == 1))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6323
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_B,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6324
				       1, &eeprom_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6325
		else
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6326
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_A,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6327
				       1, &eeprom_data);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6328
	}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6329
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6330
	/* fetch WoL from EEPROM */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6331
	if (eeprom_data & eeprom_apme_mask)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6332
		adapter->eeprom_wol |= E1000_WUFC_MAG;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6333
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6334
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6335
	 * now that we have the eeprom settings, apply the special cases
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6336
	 * where the eeprom may be wrong or the board simply won't support
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6337
	 * wake on lan on a particular port
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6338
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6339
	if (!(adapter->flags & FLAG_HAS_WOL))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6340
		adapter->eeprom_wol = 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6341
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6342
	/* initialize the wol settings based on the eeprom settings */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6343
	adapter->wol = adapter->eeprom_wol;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6344
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6345
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6346
	/* save off EEPROM version number */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6347
	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6348
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6349
	/* reset the hardware with the new settings */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6350
	e1000e_reset(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6351
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6352
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6353
	 * If the controller has AMT, do not set DRV_LOAD until the interface
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6354
	 * is up.  For all other cases, let the f/w know that the h/w is now
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6355
	 * under the control of the driver.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6356
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6357
	if (!(adapter->flags & FLAG_HAS_AMT))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6358
		e1000e_get_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6359
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6360
	strlcpy(netdev->name, "eth%d", sizeof(netdev->name));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6361
	err = register_netdev(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6362
	if (err)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6363
		goto err_register;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6364
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6365
	/* carrier off reporting is important to ethtool even BEFORE open */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6366
	netif_carrier_off(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6367
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6368
	e1000_print_device_info(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6369
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6370
	if (pci_dev_run_wake(pdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6371
		pm_runtime_put_noidle(&pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6372
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6373
	return 0;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6374
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6375
err_register:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6376
	if (!(adapter->flags & FLAG_HAS_AMT))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6377
		e1000e_release_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6378
err_eeprom:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6379
	if (hw->phy.ops.check_reset_block && !hw->phy.ops.check_reset_block(hw))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6380
		e1000_phy_hw_reset(&adapter->hw);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6381
err_hw_init:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6382
	kfree(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6383
	kfree(adapter->rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6384
err_sw_init:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6385
	if (adapter->hw.flash_address)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6386
		iounmap(adapter->hw.flash_address);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6387
	e1000e_reset_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6388
err_flashmap:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6389
	iounmap(adapter->hw.hw_addr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6390
err_ioremap:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6391
	free_netdev(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6392
err_alloc_etherdev:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6393
	pci_release_selected_regions(pdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6394
	                             pci_select_bars(pdev, IORESOURCE_MEM));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6395
err_pci_reg:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6396
err_dma:
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6397
	pci_disable_device(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6398
	return err;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6399
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6400
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6401
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6402
 * e1000_remove - Device Removal Routine
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6403
 * @pdev: PCI device information struct
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6404
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6405
 * e1000_remove is called by the PCI subsystem to alert the driver
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6406
 * that it should release a PCI device.  The could be caused by a
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6407
 * Hot-Plug event, or because the driver is going to be removed from
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6408
 * memory.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6409
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6410
static void __devexit e1000_remove(struct pci_dev *pdev)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6411
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6412
	struct net_device *netdev = pci_get_drvdata(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6413
	struct e1000_adapter *adapter = netdev_priv(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6414
	bool down = test_bit(__E1000_DOWN, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6415
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6416
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6417
	 * The timers may be rescheduled, so explicitly disable them
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6418
	 * from being rescheduled.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6419
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6420
	if (!down)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6421
		set_bit(__E1000_DOWN, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6422
	del_timer_sync(&adapter->watchdog_timer);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6423
	del_timer_sync(&adapter->phy_info_timer);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6424
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6425
	cancel_work_sync(&adapter->reset_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6426
	cancel_work_sync(&adapter->watchdog_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6427
	cancel_work_sync(&adapter->downshift_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6428
	cancel_work_sync(&adapter->update_phy_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6429
	cancel_work_sync(&adapter->print_hang_task);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6430
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6431
	if (!(netdev->flags & IFF_UP))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6432
		e1000_power_down_phy(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6433
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6434
	/* Don't lie to e1000_close() down the road. */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6435
	if (!down)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6436
		clear_bit(__E1000_DOWN, &adapter->state);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6437
	unregister_netdev(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6438
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6439
	if (pci_dev_run_wake(pdev))
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6440
		pm_runtime_get_noresume(&pdev->dev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6441
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6442
	/*
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6443
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6444
	 * would have already happened in close and is redundant.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6445
	 */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6446
	e1000e_release_hw_control(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6447
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6448
	e1000e_reset_interrupt_capability(adapter);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6449
	kfree(adapter->tx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6450
	kfree(adapter->rx_ring);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6451
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6452
	iounmap(adapter->hw.hw_addr);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6453
	if (adapter->hw.flash_address)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6454
		iounmap(adapter->hw.flash_address);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6455
	pci_release_selected_regions(pdev,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6456
	                             pci_select_bars(pdev, IORESOURCE_MEM));
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6457
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6458
	free_netdev(netdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6459
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6460
	/* AER disable */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6461
	pci_disable_pcie_error_reporting(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6462
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6463
	pci_disable_device(pdev);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6464
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6465
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6466
/* PCI Error Recovery (ERS) */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6467
static struct pci_error_handlers e1000_err_handler = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6468
	.error_detected = e1000_io_error_detected,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6469
	.slot_reset = e1000_io_slot_reset,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6470
	.resume = e1000_io_resume,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6471
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6472
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6473
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6474
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6475
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6476
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6477
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6478
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6479
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6480
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6481
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6482
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6483
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6484
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6485
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6486
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6487
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6488
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6489
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6490
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6491
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6492
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6493
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6494
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6495
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6496
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6497
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6498
	  board_80003es2lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6499
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6500
	  board_80003es2lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6501
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6502
	  board_80003es2lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6503
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6504
	  board_80003es2lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6505
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6506
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6507
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6508
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6509
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6510
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6511
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6512
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6513
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6514
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6515
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6516
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6517
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6518
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6519
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6520
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6521
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6522
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6523
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6524
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6525
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6526
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6527
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6528
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6529
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6530
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6531
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_V), board_ich10lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6532
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6533
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6534
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6535
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6536
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6537
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6538
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6539
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6540
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6541
	{ 0, 0, 0, 0, 0, 0, 0 }	/* terminate list */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6542
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6543
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6544
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6545
#ifdef CONFIG_PM
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6546
static const struct dev_pm_ops e1000_pm_ops = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6547
	SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6548
	SET_RUNTIME_PM_OPS(e1000_runtime_suspend,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6549
				e1000_runtime_resume, e1000_idle)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6550
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6551
#endif
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6552
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6553
/* PCI Device API Driver */
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6554
static struct pci_driver e1000_driver = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6555
	.name     = e1000e_driver_name,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6556
	.id_table = e1000_pci_tbl,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6557
	.probe    = e1000_probe,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6558
	.remove   = __devexit_p(e1000_remove),
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6559
#ifdef CONFIG_PM
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6560
	.driver   = {
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6561
		.pm = &e1000_pm_ops,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6562
	},
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6563
#endif
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6564
	.shutdown = e1000_shutdown,
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6565
	.err_handler = &e1000_err_handler
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6566
};
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6567
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6568
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6569
 * e1000_init_module - Driver Registration Routine
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6570
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6571
 * e1000_init_module is the first routine called when the driver is
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6572
 * loaded. All it does is register with the PCI subsystem.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6573
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6574
static int __init e1000_init_module(void)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6575
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6576
	int ret;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6577
	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6578
		e1000e_driver_version);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6579
	pr_info("Copyright(c) 1999 - 2012 Intel Corporation.\n");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6580
	ret = pci_register_driver(&e1000_driver);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6581
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6582
	return ret;
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6583
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6584
module_init(e1000_init_module);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6585
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6586
/**
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6587
 * e1000_exit_module - Driver Exit Cleanup Routine
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6588
 *
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6589
 * e1000_exit_module is called just before the driver is removed
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6590
 * from memory.
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6591
 **/
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6592
static void __exit e1000_exit_module(void)
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6593
{
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6594
	pci_unregister_driver(&e1000_driver);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6595
}
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6596
module_exit(e1000_exit_module);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6597
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6598
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6599
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6600
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6601
MODULE_LICENSE("GPL");
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6602
MODULE_VERSION(DRV_VERSION);
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6603
5e9221a78855 Added e1000e driver for kernel 3.4.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6604
/* netdev.c */