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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2588
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/* Intel PRO/1000 Linux driver
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
 * Copyright(c) 1999 - 2014 Intel Corporation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
 * This program is free software; you can redistribute it and/or modify it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
 * under the terms and conditions of the GNU General Public License,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
 * version 2, as published by the Free Software Foundation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
 * This program is distributed in the hope it will be useful, but WITHOUT
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
 * more details.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
 * The full GNU General Public License is included in this distribution in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
 * the file called "COPYING".
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
 * Contact Information:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
 * Linux NICS <linux.nics@intel.com>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
#include <linux/module.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
#include <linux/types.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
#include <linux/init.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
#include <linux/pci.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
#include <linux/vmalloc.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#include <linux/pagemap.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <linux/delay.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/netdevice.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/interrupt.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/tcp.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/ipv6.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/slab.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <net/checksum.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <net/ip6_checksum.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/ethtool.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <linux/if_vlan.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <linux/cpu.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <linux/smp.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <linux/pm_qos.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <linux/pm_runtime.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <linux/aer.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <linux/prefetch.h>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include "e1000.h"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#define DRV_EXTRAVERSION "-k"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#define DRV_VERSION "2.3.2" DRV_EXTRAVERSION
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
char e1000e_driver_name[] = "e1000e";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
const char e1000e_driver_version[] = DRV_VERSION;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV|NETIF_MSG_PROBE|NETIF_MSG_LINK)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
static int debug = -1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
module_param(debug, int, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
static const struct e1000_info *e1000_info_tbl[] = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	[board_82571]		= &e1000_82571_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	[board_82572]		= &e1000_82572_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	[board_82573]		= &e1000_82573_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	[board_82574]		= &e1000_82574_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	[board_82583]		= &e1000_82583_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	[board_80003es2lan]	= &e1000_es2_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	[board_ich8lan]		= &e1000_ich8_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	[board_ich9lan]		= &e1000_ich9_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	[board_ich10lan]	= &e1000_ich10_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	[board_pchlan]		= &e1000_pch_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	[board_pch2lan]		= &e1000_pch2_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	[board_pch_lpt]		= &e1000_pch_lpt_info,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
struct e1000_reg_info {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	u32 ofs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	char *name;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
static const struct e1000_reg_info e1000_reg_info_tbl[] = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	/* General Registers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	{E1000_CTRL, "CTRL"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	{E1000_STATUS, "STATUS"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	{E1000_CTRL_EXT, "CTRL_EXT"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	/* Interrupt Registers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	{E1000_ICR, "ICR"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	/* Rx Registers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	{E1000_RCTL, "RCTL"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	{E1000_RDLEN(0), "RDLEN"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	{E1000_RDH(0), "RDH"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	{E1000_RDT(0), "RDT"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	{E1000_RDTR, "RDTR"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	{E1000_RXDCTL(0), "RXDCTL"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	{E1000_ERT, "ERT"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	{E1000_RDBAL(0), "RDBAL"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	{E1000_RDBAH(0), "RDBAH"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	{E1000_RDFH, "RDFH"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	{E1000_RDFT, "RDFT"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	{E1000_RDFHS, "RDFHS"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	{E1000_RDFTS, "RDFTS"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	{E1000_RDFPC, "RDFPC"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	/* Tx Registers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	{E1000_TCTL, "TCTL"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	{E1000_TDBAL(0), "TDBAL"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	{E1000_TDBAH(0), "TDBAH"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	{E1000_TDLEN(0), "TDLEN"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	{E1000_TDH(0), "TDH"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	{E1000_TDT(0), "TDT"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	{E1000_TIDV, "TIDV"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	{E1000_TXDCTL(0), "TXDCTL"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	{E1000_TADV, "TADV"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	{E1000_TARC(0), "TARC"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	{E1000_TDFH, "TDFH"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	{E1000_TDFT, "TDFT"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	{E1000_TDFHS, "TDFHS"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	{E1000_TDFTS, "TDFTS"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	{E1000_TDFPC, "TDFPC"},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	/* List Terminator */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	{0, NULL}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
 * __ew32_prepare - prepare to write to MAC CSR register on certain parts
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
 * @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
 * When updating the MAC CSR registers, the Manageability Engine (ME) could
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
 * be accessing the registers at the same time.  Normally, this is handled in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
 * h/w by an arbiter but on some parts there is a bug that acknowledges Host
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
 * accesses later than it should which could result in the register to have
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
 * an incorrect value.  Workaround this by checking the FWSM register which
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
 * has bit 24 set while ME is accessing MAC CSR registers, wait if it is set
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
 * and try again a number of times.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
s32 __ew32_prepare(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
		udelay(50);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	return i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
	if (hw->adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
		__ew32_prepare(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	writel(val, hw->hw_addr + reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
 * e1000_regdump - register printout routine
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
 * @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
 * @reginfo: pointer to the register info table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	int n = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
	char rname[16];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
	u32 regs[8];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
	switch (reginfo->ofs) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
	case E1000_RXDCTL(0):
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		for (n = 0; n < 2; n++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
			regs[n] = __er32(hw, E1000_RXDCTL(n));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
	case E1000_TXDCTL(0):
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		for (n = 0; n < 2; n++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
			regs[n] = __er32(hw, E1000_TXDCTL(n));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	case E1000_TARC(0):
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
		for (n = 0; n < 2; n++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
			regs[n] = __er32(hw, E1000_TARC(n));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
		pr_info("%-15s %08x\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
			reginfo->name, __er32(hw, reginfo->ofs));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
	snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
static void e1000e_dump_ps_pages(struct e1000_adapter *adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
				 struct e1000_buffer *bi)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	struct e1000_ps_page *ps_page;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	for (i = 0; i < adapter->rx_ps_pages; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		ps_page = &bi->ps_pages[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		if (ps_page->page) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
			pr_info("packet dump for ps_page %d:\n", i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
				       16, 1, page_address(ps_page->page),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
				       PAGE_SIZE, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
 * e1000e_dump - Print registers, Tx-ring and Rx-ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
static void e1000e_dump(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	struct e1000_reg_info *reginfo;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	struct e1000_ring *tx_ring = adapter->tx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	struct e1000_tx_desc *tx_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	struct my_u0 {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
		__le64 a;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
		__le64 b;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	} *u0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	struct e1000_ring *rx_ring = adapter->rx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	union e1000_rx_desc_packet_split *rx_desc_ps;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	union e1000_rx_desc_extended *rx_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	struct my_u1 {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
		__le64 a;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
		__le64 b;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
		__le64 c;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
		__le64 d;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	} *u1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	u32 staterr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	int i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	if (!netif_msg_hw(adapter))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	/* Print netdevice Info */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	if (netdev) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
		dev_info(&adapter->pdev->dev, "Net device Info\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
		pr_info("Device Name     state            trans_start      last_rx\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
		pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
			netdev->state, netdev->trans_start, netdev->last_rx);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	/* Print Registers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	dev_info(&adapter->pdev->dev, "Register Dump\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	pr_info(" Register Name   Value\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	     reginfo->name; reginfo++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
		e1000_regdump(hw, reginfo);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	/* Print Tx Ring Summary */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	if (!netdev || !netif_running(netdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	dev_info(&adapter->pdev->dev, "Tx Ring Summary\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	pr_info("Queue [NTU] [NTC] [bi(ntc)->dma  ] leng ntw timestamp\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
		0, tx_ring->next_to_use, tx_ring->next_to_clean,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
		(unsigned long long)buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		buffer_info->length,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
		buffer_info->next_to_watch,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
		(unsigned long long)buffer_info->time_stamp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	/* Print Tx Ring */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	if (!netif_msg_tx_done(adapter))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
		goto rx_ring_summary;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	dev_info(&adapter->pdev->dev, "Tx Ring Dump\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
	 * Legacy Transmit Descriptor
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	 *   +--------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	 *   +--------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	 *   +--------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	 *   63       48 47        36 35    32 31     24 23    16 15        0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	 *   63      48 47    40 39       32 31             16 15    8 7      0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	 *   +----------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	 *   +----------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	 *   +----------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	 * Extended Data Descriptor (DTYP=0x1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	 *   +----------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	 * 0 |                     Buffer Address [63:0]                      |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	 *   +----------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	 *   +----------------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	pr_info("Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Legacy format\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	pr_info("Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Context format\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	pr_info("Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen] [bi->dma       ] leng  ntw timestamp        bi->skb <-- Ext Data format\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		const char *next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		tx_desc = E1000_TX_DESC(*tx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
		u0 = (struct my_u0 *)tx_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
			next_desc = " NTC/U";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		else if (i == tx_ring->next_to_use)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
			next_desc = " NTU";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
		else if (i == tx_ring->next_to_clean)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
			next_desc = " NTC";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
			next_desc = "";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
		pr_info("T%c[0x%03X]    %016llX %016llX %016llX %04X  %3X %016llX %p%s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
			(!(le64_to_cpu(u0->b) & (1 << 29)) ? 'l' :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
			 ((le64_to_cpu(u0->b) & (1 << 20)) ? 'd' : 'c')),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
			i,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
			(unsigned long long)le64_to_cpu(u0->a),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
			(unsigned long long)le64_to_cpu(u0->b),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
			(unsigned long long)buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
			buffer_info->length, buffer_info->next_to_watch,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
			(unsigned long long)buffer_info->time_stamp,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
			buffer_info->skb, next_desc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		if (netif_msg_pktdata(adapter) && buffer_info->skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
				       16, 1, buffer_info->skb->data,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
				       buffer_info->skb->len, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	/* Print Rx Ring Summary */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
rx_ring_summary:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	dev_info(&adapter->pdev->dev, "Rx Ring Summary\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	pr_info("Queue [NTU] [NTC]\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	pr_info(" %5d %5X %5X\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		0, rx_ring->next_to_use, rx_ring->next_to_clean);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	/* Print Rx Ring */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	if (!netif_msg_rx_status(adapter))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
	dev_info(&adapter->pdev->dev, "Rx Ring Dump\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
	switch (adapter->rx_ps_pages) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
	case 1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
	case 2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	case 3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
		/* [Extended] Packet Split Receive Descriptor Format
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
		 *    +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
		 *  0 |                Buffer Address 0 [63:0]              |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
		 *    +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
		 *  8 |                Buffer Address 1 [63:0]              |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
		 *    +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
		 * 16 |                Buffer Address 2 [63:0]              |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
		 *    +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
		 * 24 |                Buffer Address 3 [63:0]              |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		 *    +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
		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");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
		/* [Extended] Receive Descriptor (Write-Back) Format
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
		 *   63       48 47    32 31     13 12    8 7    4 3        0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		 *   +------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
		 * 0 | Packet   | IP     |  Rsvd   | MRQ   | Rsvd | MRQ RSS |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		 *   | Checksum | Ident  |         | Queue |      |  Type   |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
		 *   +------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
		 *   +------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
		 *   63       48 47    32 31            20 19               0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		pr_info("RWB[desc]      [ck ipid mrqhsh] [vl   l0 ee  es] [ l3  l2  l1 hs] [reserved      ] ---------------- [bi->skb] <-- Ext Rx Write-Back format\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		for (i = 0; i < rx_ring->count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
			const char *next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
			buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
			rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
			u1 = (struct my_u1 *)rx_desc_ps;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
			staterr =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
			    le32_to_cpu(rx_desc_ps->wb.middle.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			if (i == rx_ring->next_to_use)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
				next_desc = " NTU";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
			else if (i == rx_ring->next_to_clean)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
				next_desc = " NTC";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
				next_desc = "";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
			if (staterr & E1000_RXD_STAT_DD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
				/* Descriptor Done */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX ---------------- %p%s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
					"RWB", i,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
					(unsigned long long)le64_to_cpu(u1->a),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
					(unsigned long long)le64_to_cpu(u1->b),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
					(unsigned long long)le64_to_cpu(u1->c),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
					(unsigned long long)le64_to_cpu(u1->d),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
					buffer_info->skb, next_desc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %016llX %016llX %p%s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
					"R  ", i,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
					(unsigned long long)le64_to_cpu(u1->a),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
					(unsigned long long)le64_to_cpu(u1->b),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
					(unsigned long long)le64_to_cpu(u1->c),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
					(unsigned long long)le64_to_cpu(u1->d),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
					(unsigned long long)buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
					buffer_info->skb, next_desc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
				if (netif_msg_pktdata(adapter))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
					e1000e_dump_ps_pages(adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
							     buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	case 0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
		/* Extended Receive Descriptor (Read) Format
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
		 *   +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
		 * 0 |                Buffer Address [63:0]                |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
		 *   +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
		 * 8 |                      Reserved                       |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		 *   +-----------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
		pr_info("R  [desc]      [buf addr 63:0 ] [reserved 63:0 ] [bi->dma       ] [bi->skb] <-- Ext (Read) format\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		/* Extended Receive Descriptor (Write-Back) Format
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
		 *   63       48 47    32 31    24 23            4 3        0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
		 *   +------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		 *   |     RSS Hash      |        |               |         |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
		 * 0 +-------------------+  Rsvd  |   Reserved    | MRQ RSS |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
		 *   | Packet   | IP     |        |               |  Type   |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
		 *   | Checksum | Ident  |        |               |         |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
		 *   +------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		 *   +------------------------------------------------------+
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		 *   63       48 47    32 31            20 19               0
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
		pr_info("RWB[desc]      [cs ipid    mrq] [vt   ln xe  xs] [bi->skb] <-- Ext (Write-Back) format\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
		for (i = 0; i < rx_ring->count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
			const char *next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
			buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
			rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
			u1 = (struct my_u1 *)rx_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
			staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
			if (i == rx_ring->next_to_use)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
				next_desc = " NTU";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
			else if (i == rx_ring->next_to_clean)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
				next_desc = " NTC";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
				next_desc = "";
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
			if (staterr & E1000_RXD_STAT_DD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
				/* Descriptor Done */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
				pr_info("%s[0x%03X]     %016llX %016llX ---------------- %p%s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
					"RWB", i,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
					(unsigned long long)le64_to_cpu(u1->a),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
					(unsigned long long)le64_to_cpu(u1->b),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
					buffer_info->skb, next_desc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
				pr_info("%s[0x%03X]     %016llX %016llX %016llX %p%s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
					"R  ", i,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
					(unsigned long long)le64_to_cpu(u1->a),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
					(unsigned long long)le64_to_cpu(u1->b),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
					(unsigned long long)buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
					buffer_info->skb, next_desc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
				if (netif_msg_pktdata(adapter) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
				    buffer_info->skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
					print_hex_dump(KERN_INFO, "",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
						       DUMP_PREFIX_ADDRESS, 16,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
						       1,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
						       buffer_info->skb->data,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
						       adapter->rx_buffer_len,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
						       true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
 * e1000_desc_unused - calculate if we have unused descriptors
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
static int e1000_desc_unused(struct e1000_ring *ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	if (ring->next_to_clean > ring->next_to_use)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		return ring->next_to_clean - ring->next_to_use - 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
 * e1000e_systim_to_hwtstamp - convert system time value to hw time stamp
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
 * @hwtstamps: time stamp structure to update
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
 * @systim: unsigned 64bit system time value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
 * Convert the system time value stored in the RX/TXSTMP registers into a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
 * hwtstamp which can be used by the upper level time stamping functions.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
 * The 'systim_lock' spinlock is used to protect the consistency of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
 * system time value. This is needed because reading the 64 bit time
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
 * value involves reading two 32 bit registers. The first read latches the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
 * value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
static void e1000e_systim_to_hwtstamp(struct e1000_adapter *adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
				      struct skb_shared_hwtstamps *hwtstamps,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
				      u64 systim)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	u64 ns;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	unsigned long flags;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	spin_lock_irqsave(&adapter->systim_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	ns = timecounter_cyc2time(&adapter->tc, systim);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	spin_unlock_irqrestore(&adapter->systim_lock, flags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	memset(hwtstamps, 0, sizeof(*hwtstamps));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	hwtstamps->hwtstamp = ns_to_ktime(ns);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
 * e1000e_rx_hwtstamp - utility function which checks for Rx time stamp
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
 * @status: descriptor extended error and status field
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
 * @skb: particular skb to include time stamp
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
 * If the time stamp is valid, convert it into the timecounter ns value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
 * and store that result into the shhwtstamps structure which is passed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
 * up the network stack.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
static void e1000e_rx_hwtstamp(struct e1000_adapter *adapter, u32 status,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
			       struct sk_buff *skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	u64 rxstmp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	    !(status & E1000_RXDEXT_STATERR_TST) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	    !(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	/* The Rx time stamp registers contain the time stamp.  No other
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	 * received packet will be time stamped until the Rx time stamp
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	 * registers are read.  Because only one packet can be time stamped
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	 * at a time, the register values must belong to this packet and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	 * therefore none of the other additional attributes need to be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	 * compared.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	rxstmp = (u64)er32(RXSTMPL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	rxstmp |= (u64)er32(RXSTMPH) << 32;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	e1000e_systim_to_hwtstamp(adapter, skb_hwtstamps(skb), rxstmp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	adapter->flags2 &= ~FLAG2_CHECK_RX_HWTSTAMP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
 * e1000_receive_skb - helper function to handle Rx indications
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
 * @staterr: descriptor extended error and status field as written by hardware
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
 * @skb: pointer to sk_buff to be indicated to stack
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
static void e1000_receive_skb(struct e1000_adapter *adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
			      struct net_device *netdev, struct sk_buff *skb,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
			      u32 staterr, __le16 vlan)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
	u16 tag = le16_to_cpu(vlan);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	e1000e_rx_hwtstamp(adapter, staterr, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	skb->protocol = eth_type_trans(skb, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	if (staterr & E1000_RXD_STAT_VP)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), tag);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	napi_gro_receive(&adapter->napi, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
 * e1000_rx_checksum - Receive Checksum Offload
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
 * @status_err: receive descriptor status and error fields
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
 * @csum: receive descriptor csum field
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
 * @sk_buff: socket buffer with received data
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
			      struct sk_buff *skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	u16 status = (u16)status_err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	u8 errors = (u8)(status_err >> 24);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	skb_checksum_none_assert(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	/* Rx checksum disabled */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	if (!(adapter->netdev->features & NETIF_F_RXCSUM))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	/* Ignore Checksum bit is set */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	if (status & E1000_RXD_STAT_IXSM)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	/* TCP/UDP checksum error bit or IP checksum error bit is set */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		/* let the stack verify checksum errors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		adapter->hw_csum_err++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	/* TCP/UDP Checksum has not been calculated */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	/* It must be a TCP or UDP packet with a valid checksum */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	skb->ip_summed = CHECKSUM_UNNECESSARY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	adapter->hw_csum_good++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	s32 ret_val = __ew32_prepare(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	writel(i, rx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		u32 rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		e_err("ME firmware caused invalid RDT - resetting\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
		schedule_work(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	s32 ret_val = __ew32_prepare(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	writel(i, tx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
	if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		u32 tctl = er32(TCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		ew32(TCTL, tctl & ~E1000_TCTL_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		e_err("ME firmware caused invalid TDT - resetting\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		schedule_work(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
 * e1000_alloc_rx_buffers - Replace used receive buffers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
				   int cleaned_count, gfp_t gfp)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	union e1000_rx_desc_extended *rx_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	struct sk_buff *skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	unsigned int bufsz = adapter->rx_buffer_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	i = rx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	while (cleaned_count--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		skb = buffer_info->skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		if (skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
			skb_trim(skb, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
			goto map_skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
		if (!skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
			/* Better luck next round */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
			adapter->alloc_rx_buff_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
		buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
map_skb:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
						  adapter->rx_buffer_len,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
						  DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
			dev_err(&pdev->dev, "Rx DMA map failed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
			adapter->rx_dma_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
			/* Force memory writes to complete before letting h/w
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
			 * know there are new descriptors to fetch.  (Only
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
			 * applicable for weak-ordered memory model archs,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
			 * such as IA-64).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
			wmb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
				e1000e_update_rdt_wa(rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
				writel(i, rx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
		i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
		if (i == rx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
			i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
		buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	rx_ring->next_to_use = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
				      int cleaned_count, gfp_t gfp)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	union e1000_rx_desc_packet_split *rx_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	struct e1000_ps_page *ps_page;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	struct sk_buff *skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	unsigned int i, j;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	i = rx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	while (cleaned_count--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
			ps_page = &buffer_info->ps_pages[j];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
			if (j >= adapter->rx_ps_pages) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
				/* all unused desc entries get hw null ptr */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
				rx_desc->read.buffer_addr[j + 1] =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
				    ~cpu_to_le64(0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
				continue;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
			if (!ps_page->page) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
				ps_page->page = alloc_page(gfp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
				if (!ps_page->page) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
					adapter->alloc_rx_buff_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
					goto no_buffers;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
				ps_page->dma = dma_map_page(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
							    ps_page->page,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
							    0, PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
							    DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
				if (dma_mapping_error(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
						      ps_page->dma)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
					dev_err(&adapter->pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
						"Rx DMA page map failed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
					adapter->rx_dma_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
					goto no_buffers;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
			/* Refresh the desc even if buffer_addrs
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
			 * didn't change because each write-back
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
			 * erases this info.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
			rx_desc->read.buffer_addr[j + 1] =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
			    cpu_to_le64(ps_page->dma);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		skb = __netdev_alloc_skb_ip_align(netdev, adapter->rx_ps_bsize0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
						  gfp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		if (!skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
			adapter->alloc_rx_buff_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
						  adapter->rx_ps_bsize0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
						  DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
			dev_err(&pdev->dev, "Rx DMA map failed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
			adapter->rx_dma_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
			/* cleanup skb */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
			dev_kfree_skb_any(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
			buffer_info->skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
			/* Force memory writes to complete before letting h/w
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
			 * know there are new descriptors to fetch.  (Only
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
			 * applicable for weak-ordered memory model archs,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
			 * such as IA-64).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
			wmb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
			if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
				e1000e_update_rdt_wa(rx_ring, i << 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
				writel(i << 1, rx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		if (i == rx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
			i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
no_buffers:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	rx_ring->next_to_use = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
 * @cleaned_count: number of buffers to allocate this pass
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
					 int cleaned_count, gfp_t gfp)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	union e1000_rx_desc_extended *rx_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	struct sk_buff *skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	unsigned int bufsz = 256 - 16;	/* for skb_reserve */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	i = rx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
	while (cleaned_count--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
		skb = buffer_info->skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
		if (skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
			skb_trim(skb, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
			goto check_page;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
		skb = __netdev_alloc_skb_ip_align(netdev, bufsz, gfp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
		if (unlikely(!skb)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
			/* Better luck next round */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
			adapter->alloc_rx_buff_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
check_page:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
		/* allocate a new page if necessary */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
		if (!buffer_info->page) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
			buffer_info->page = alloc_page(gfp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
			if (unlikely(!buffer_info->page)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
				adapter->alloc_rx_buff_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
		if (!buffer_info->dma) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
			buffer_info->dma = dma_map_page(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
							buffer_info->page, 0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
							PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
							DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
			if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
				adapter->alloc_rx_buff_failed++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		if (unlikely(++i == rx_ring->count))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
			i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	if (likely(rx_ring->next_to_use != i)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		rx_ring->next_to_use = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		if (unlikely(i-- == 0))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
			i = (rx_ring->count - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		/* Force memory writes to complete before letting h/w
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
		 * know there are new descriptors to fetch.  (Only
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		 * applicable for weak-ordered memory model archs,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
		 * such as IA-64).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
		wmb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
		if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
			e1000e_update_rdt_wa(rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
			writel(i, rx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
				 struct sk_buff *skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	if (netdev->features & NETIF_F_RXHASH)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
		skb_set_hash(skb, le32_to_cpu(rss), PKT_HASH_TYPE_L3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
 * e1000_clean_rx_irq - Send received data up the network stack
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
 * the return value indicates whether actual cleaning was done, there
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
 * is no guarantee that everything was cleaned
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
			       int work_to_do)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	struct e1000_buffer *buffer_info, *next_buffer;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	u32 length, staterr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	int cleaned_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	bool cleaned = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	i = rx_ring->next_to_clean;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	while (staterr & E1000_RXD_STAT_DD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
		struct sk_buff *skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		if (*work_done >= work_to_do)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		(*work_done)++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
		rmb();	/* read descriptor and rx_buffer_info after status DD */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
		skb = buffer_info->skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
		buffer_info->skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
		prefetch(skb->data - NET_IP_ALIGN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
		if (i == rx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
			i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
		prefetch(next_rxd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
		next_buffer = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
		cleaned = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
		cleaned_count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
		dma_unmap_single(&pdev->dev, buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
				 adapter->rx_buffer_len, DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
		buffer_info->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
		length = le16_to_cpu(rx_desc->wb.upper.length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
		/* !EOP means multiple descriptors were used to store a single
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		 * packet, if that's the case we need to toss it.  In fact, we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
		 * need to toss every packet with the EOP bit clear and the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		 * next frame that _does_ have the EOP bit set, as it is by
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
		 * definition only a frame fragment
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
		if (unlikely(!(staterr & E1000_RXD_STAT_EOP)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
			adapter->flags2 |= FLAG2_IS_DISCARDING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
			/* All receives must fit into a single buffer */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
			e_dbg("Receive packet consumed multiple buffers\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
			/* recycle */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
			buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
			if (staterr & E1000_RXD_STAT_EOP)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
			     !(netdev->features & NETIF_F_RXALL))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
			/* recycle */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
			buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		/* adjust length to remove Ethernet CRC */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
			/* If configured to store CRC, don't subtract FCS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
			 * but keep the FCS bytes out of the total_rx_bytes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
			 * counter
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
			if (netdev->features & NETIF_F_RXFCS)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
				total_rx_bytes -= 4;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
				length -= 4;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
		total_rx_bytes += length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
		total_rx_packets++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		/* code added for copybreak, this should improve
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
		 * performance for small packets with large amounts
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		 * of reassembly being done in the stack
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		if (length < copybreak) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
			struct sk_buff *new_skb =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
			    netdev_alloc_skb_ip_align(netdev, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
			if (new_skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
				skb_copy_to_linear_data_offset(new_skb,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
							       -NET_IP_ALIGN,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
							       (skb->data -
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
								NET_IP_ALIGN),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
							       (length +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
								NET_IP_ALIGN));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
				/* save the skb in buffer_info as good */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
				buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
				skb = new_skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
			/* else just continue with the old one */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		/* end copybreak code */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		skb_put(skb, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		/* Receive Checksum Offload */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		e1000_rx_checksum(adapter, staterr, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		e1000_receive_skb(adapter, netdev, skb, staterr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
				  rx_desc->wb.upper.vlan);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
next_desc:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		/* return some buffers to hardware, one at a time is too slow */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
					      GFP_ATOMIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
			cleaned_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		/* use prefetched values */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		rx_desc = next_rxd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		buffer_info = next_buffer;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	rx_ring->next_to_clean = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	cleaned_count = e1000_desc_unused(rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
	if (cleaned_count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
	adapter->total_rx_bytes += total_rx_bytes;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
	adapter->total_rx_packets += total_rx_packets;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	return cleaned;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
static void e1000_put_txbuf(struct e1000_ring *tx_ring,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
			    struct e1000_buffer *buffer_info)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	if (buffer_info->dma) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		if (buffer_info->mapped_as_page)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
				       buffer_info->length, DMA_TO_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
					 buffer_info->length, DMA_TO_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		buffer_info->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	if (buffer_info->skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		dev_kfree_skb_any(buffer_info->skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		buffer_info->skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	buffer_info->time_stamp = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
static void e1000_print_hw_hang(struct work_struct *work)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	struct e1000_adapter *adapter = container_of(work,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
						     struct e1000_adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
						     print_hang_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	struct e1000_ring *tx_ring = adapter->tx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	unsigned int i = tx_ring->next_to_clean;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
	u16 phy_status, phy_1000t_status, phy_ext_status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
	u16 pci_status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
	if (test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
	if (!adapter->tx_hang_recheck && (adapter->flags2 & FLAG2_DMA_BURST)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		/* May be block on write-back, flush and detect again
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		 * flush pending descriptor writebacks to memory
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		/* execute the writes immediately */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
		e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
		/* Due to rare timing issues, write to TIDV again to ensure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		 * the write is successful
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
		/* execute the writes immediately */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
		adapter->tx_hang_recheck = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
	adapter->tx_hang_recheck = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
	if (er32(TDH(0)) == er32(TDT(0))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		e_dbg("false hang detected, ignoring\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	/* Real hang detected */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
	netif_stop_queue(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	e1e_rphy(hw, MII_BMSR, &phy_status);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
	e1e_rphy(hw, MII_STAT1000, &phy_1000t_status);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	e1e_rphy(hw, MII_ESTATUS, &phy_ext_status);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	/* detected Hardware unit hang */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
	e_err("Detected Hardware Unit Hang:\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	      "  TDH                  <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
	      "  TDT                  <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	      "  next_to_use          <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
	      "  next_to_clean        <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	      "buffer_info[next_to_clean]:\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
	      "  time_stamp           <%lx>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	      "  next_to_watch        <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	      "  jiffies              <%lx>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
	      "  next_to_watch.status <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
	      "MAC Status             <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
	      "PHY Status             <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	      "PHY 1000BASE-T Status  <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	      "PHY Extended Status    <%x>\n"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	      "PCI Status             <%x>\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	      readl(tx_ring->head), readl(tx_ring->tail), tx_ring->next_to_use,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	      tx_ring->next_to_clean, tx_ring->buffer_info[eop].time_stamp,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	      eop, jiffies, eop_desc->upper.fields.status, er32(STATUS),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	      phy_status, phy_1000t_status, phy_ext_status, pci_status);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	e1000e_dump(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	/* Suggest workaround for known h/w issue */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	if ((hw->mac.type == e1000_pchlan) && (er32(CTRL) & E1000_CTRL_TFCE))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		e_err("Try turning off Tx pause (flow control) via ethtool\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
 * e1000e_tx_hwtstamp_work - check for Tx time stamp
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
 * @work: pointer to work struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
 * This work function polls the TSYNCTXCTL valid bit to determine when a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
 * timestamp has been taken for the current stored skb.  The timestamp must
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
 * be for this skb because only one such packet is allowed in the queue.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
static void e1000e_tx_hwtstamp_work(struct work_struct *work)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	struct e1000_adapter *adapter = container_of(work, struct e1000_adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
						     tx_hwtstamp_work);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
	if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
		struct skb_shared_hwtstamps shhwtstamps;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		u64 txstmp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		txstmp = er32(TXSTMPL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
		txstmp |= (u64)er32(TXSTMPH) << 32;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
		e1000e_systim_to_hwtstamp(adapter, &shhwtstamps, txstmp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
		skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
		dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		adapter->tx_hwtstamp_skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	} else if (time_after(jiffies, adapter->tx_hwtstamp_start
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
			      + adapter->tx_timeout_factor * HZ)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		adapter->tx_hwtstamp_skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		adapter->tx_hwtstamp_timeouts++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		e_warn("clearing Tx timestamp hang\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
		/* reschedule to check later */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		schedule_work(&adapter->tx_hwtstamp_work);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
 * @tx_ring: Tx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
 * the return value indicates whether actual cleaning was done, there
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
 * is no guarantee that everything was cleaned
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
	struct e1000_tx_desc *tx_desc, *eop_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
	unsigned int i, eop;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	unsigned int count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
	unsigned int bytes_compl = 0, pkts_compl = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	i = tx_ring->next_to_clean;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
	eop = tx_ring->buffer_info[i].next_to_watch;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	       (count < tx_ring->count)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		bool cleaned = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		rmb();		/* read buffer_info after eop_desc */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		for (; !cleaned; count++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
			tx_desc = E1000_TX_DESC(*tx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
			buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
			cleaned = (i == eop);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
			if (cleaned) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
				total_tx_packets += buffer_info->segs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
				total_tx_bytes += buffer_info->bytecount;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
				if (buffer_info->skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
					bytes_compl += buffer_info->skb->len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
					pkts_compl++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
			e1000_put_txbuf(tx_ring, buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
			tx_desc->upper.data = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
			i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
			if (i == tx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
				i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		if (i == tx_ring->next_to_use)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
		eop = tx_ring->buffer_info[i].next_to_watch;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	tx_ring->next_to_clean = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
#define TX_WAKE_THRESHOLD 32
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	if (count && netif_carrier_ok(netdev) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
		/* Make sure that anybody stopping the queue after this
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
		 * sees the new next_to_clean.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		smp_mb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		if (netif_queue_stopped(netdev) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
			netif_wake_queue(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
			++adapter->restart_queue;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	if (adapter->detect_tx_hung) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		/* Detect a transmit hang in hardware, this serializes the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		 * check with the clearing of time_stamp and movement of i
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
		adapter->detect_tx_hung = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		if (tx_ring->buffer_info[i].time_stamp &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
			       + (adapter->tx_timeout_factor * HZ)) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		    !(er32(STATUS) & E1000_STATUS_TXOFF))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
			schedule_work(&adapter->print_hang_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
			adapter->tx_hang_recheck = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	adapter->total_tx_bytes += total_tx_bytes;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	adapter->total_tx_packets += total_tx_packets;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	return count < tx_ring->count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
 * the return value indicates whether actual cleaning was done, there
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
 * is no guarantee that everything was cleaned
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
				  int work_to_do)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
	struct e1000_buffer *buffer_info, *next_buffer;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	struct e1000_ps_page *ps_page;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
	struct sk_buff *skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	unsigned int i, j;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	u32 length, staterr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	int cleaned_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	bool cleaned = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
	i = rx_ring->next_to_clean;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	while (staterr & E1000_RXD_STAT_DD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
		if (*work_done >= work_to_do)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		(*work_done)++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		skb = buffer_info->skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		rmb();	/* read descriptor and rx_buffer_info after status DD */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
		/* in the packet split case this is header only */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
		prefetch(skb->data - NET_IP_ALIGN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
		i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		if (i == rx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
			i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		prefetch(next_rxd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
		next_buffer = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		cleaned = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		cleaned_count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
		dma_unmap_single(&pdev->dev, buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
				 adapter->rx_ps_bsize0, DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
		buffer_info->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		/* see !EOP comment in other Rx routine */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		if (!(staterr & E1000_RXD_STAT_EOP))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
			adapter->flags2 |= FLAG2_IS_DISCARDING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
			e_dbg("Packet Split buffers didn't pick up the full packet\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
			dev_kfree_skb_irq(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
			if (staterr & E1000_RXD_STAT_EOP)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		if (unlikely((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
			     !(netdev->features & NETIF_F_RXALL))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
			dev_kfree_skb_irq(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
		length = le16_to_cpu(rx_desc->wb.middle.length0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
		if (!length) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
			e_dbg("Last part of the packet spanning multiple descriptors\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
			dev_kfree_skb_irq(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
		/* Good Receive */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		skb_put(skb, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
			/* this looks ugly, but it seems compiler issues make
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
			 * it more efficient than reusing j
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
			int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
			/* page alloc/put takes too long and effects small
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
			 * packet throughput, so unsplit small packets and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
			 * save the alloc/put only valid in softirq (napi)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
			 * context to call kmap_*
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
			if (l1 && (l1 <= copybreak) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			    ((length + l1) <= adapter->rx_ps_bsize0)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
				u8 *vaddr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
				ps_page = &buffer_info->ps_pages[0];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
				/* there is no documentation about how to call
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
				 * kmap_atomic, so we can't hold the mapping
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
				 * very long
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
				 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
				dma_sync_single_for_cpu(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
							ps_page->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
							PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
							DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
				vaddr = kmap_atomic(ps_page->page);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
				memcpy(skb_tail_pointer(skb), vaddr, l1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
				kunmap_atomic(vaddr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
				dma_sync_single_for_device(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
							   ps_page->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
							   PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
							   DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
				/* remove the CRC */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
				if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
					if (!(netdev->features & NETIF_F_RXFCS))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
						l1 -= 4;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
				skb_put(skb, l1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
				goto copydone;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
			}	/* if */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
			if (!length)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
			ps_page = &buffer_info->ps_pages[j];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
				       DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
			ps_page->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
			skb_fill_page_desc(skb, j, ps_page->page, 0, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
			ps_page->page = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
			skb->len += length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
			skb->data_len += length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
			skb->truesize += PAGE_SIZE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		/* strip the ethernet crc, problem is we're using pages now so
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
		 * this whole operation can get a little cpu intensive
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
			if (!(netdev->features & NETIF_F_RXFCS))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
				pskb_trim(skb, skb->len - 4);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
copydone:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
		total_rx_bytes += skb->len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
		total_rx_packets++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
		e1000_rx_checksum(adapter, staterr, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
		if (rx_desc->wb.upper.header_status &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
		    cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
			adapter->rx_hdr_split++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		e1000_receive_skb(adapter, netdev, skb, staterr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
				  rx_desc->wb.middle.vlan);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
next_desc:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		buffer_info->skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
		/* return some buffers to hardware, one at a time is too slow */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
					      GFP_ATOMIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
			cleaned_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
		/* use prefetched values */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
		rx_desc = next_rxd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		buffer_info = next_buffer;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
	rx_ring->next_to_clean = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	cleaned_count = e1000_desc_unused(rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	if (cleaned_count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	adapter->total_rx_bytes += total_rx_bytes;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	adapter->total_rx_packets += total_rx_packets;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	return cleaned;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
 * e1000_consume_page - helper function
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
			       u16 length)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	bi->page = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	skb->len += length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	skb->data_len += length;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
	skb->truesize += PAGE_SIZE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
 * the return value indicates whether actual cleaning was done, there
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
 * is no guarantee that everything was cleaned
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
				     int work_to_do)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	union e1000_rx_desc_extended *rx_desc, *next_rxd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	struct e1000_buffer *buffer_info, *next_buffer;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	u32 length, staterr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	int cleaned_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
	bool cleaned = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
	struct skb_shared_info *shinfo;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	i = rx_ring->next_to_clean;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	while (staterr & E1000_RXD_STAT_DD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
		struct sk_buff *skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		if (*work_done >= work_to_do)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
		(*work_done)++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		rmb();	/* read descriptor and rx_buffer_info after status DD */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
		skb = buffer_info->skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		buffer_info->skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		++i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		if (i == rx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
			i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		next_rxd = E1000_RX_DESC_EXT(*rx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
		prefetch(next_rxd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		next_buffer = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		cleaned = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		cleaned_count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		dma_unmap_page(&pdev->dev, buffer_info->dma, PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
			       DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
		buffer_info->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		length = le16_to_cpu(rx_desc->wb.upper.length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		/* errors is only valid for DD + EOP descriptors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		if (unlikely((staterr & E1000_RXD_STAT_EOP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
			     ((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
			      !(netdev->features & NETIF_F_RXALL)))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
			/* recycle both page and skb */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
			buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
			/* an error means any chain goes out the window too */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
			if (rx_ring->rx_skb_top)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
				dev_kfree_skb_irq(rx_ring->rx_skb_top);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
			rx_ring->rx_skb_top = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
#define rxtop (rx_ring->rx_skb_top)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		if (!(staterr & E1000_RXD_STAT_EOP)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
			/* this descriptor is only the beginning (or middle) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
			if (!rxtop) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
				/* this is the beginning of a chain */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
				rxtop = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
						   0, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
				/* this is the middle of a chain */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
				shinfo = skb_shinfo(rxtop);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
				skb_fill_page_desc(rxtop, shinfo->nr_frags,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
						   buffer_info->page, 0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
						   length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
				/* re-use the skb, only consumed the page */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
				buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
			e1000_consume_page(buffer_info, rxtop, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
			if (rxtop) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
				/* end of the chain */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
				shinfo = skb_shinfo(rxtop);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
				skb_fill_page_desc(rxtop, shinfo->nr_frags,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
						   buffer_info->page, 0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
						   length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
				/* re-use the current skb, we only consumed the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
				 * page
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
				 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
				buffer_info->skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
				skb = rxtop;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
				rxtop = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
				e1000_consume_page(buffer_info, skb, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
				/* no chain, got EOP, this buf is the packet
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
				 * copybreak to save the put_page/alloc_page
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
				 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
				if (length <= copybreak &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
				    skb_tailroom(skb) >= length) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
					u8 *vaddr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
					vaddr = kmap_atomic(buffer_info->page);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
					memcpy(skb_tail_pointer(skb), vaddr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
					       length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
					kunmap_atomic(vaddr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
					/* re-use the page, so don't erase
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
					 * buffer_info->page
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
					 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
					skb_put(skb, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
				} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
					skb_fill_page_desc(skb, 0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
							   buffer_info->page, 0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
							   length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
					e1000_consume_page(buffer_info, skb,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
							   length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
		/* Receive Checksum Offload */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		e1000_rx_checksum(adapter, staterr, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		/* probably a little skewed due to removing CRC */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		total_rx_bytes += skb->len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		total_rx_packets++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		/* eth type trans needs skb->data to point to something */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		if (!pskb_may_pull(skb, ETH_HLEN)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
			e_err("pskb_may_pull failed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
			dev_kfree_skb_irq(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
			goto next_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		e1000_receive_skb(adapter, netdev, skb, staterr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
				  rx_desc->wb.upper.vlan);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
next_desc:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		rx_desc->wb.upper.status_error &= cpu_to_le32(~0xFF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		/* return some buffers to hardware, one at a time is too slow */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
			adapter->alloc_rx_buf(rx_ring, cleaned_count,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
					      GFP_ATOMIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
			cleaned_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
		/* use prefetched values */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
		rx_desc = next_rxd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
		buffer_info = next_buffer;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	rx_ring->next_to_clean = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	cleaned_count = e1000_desc_unused(rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	if (cleaned_count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
		adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	adapter->total_rx_bytes += total_rx_bytes;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
	adapter->total_rx_packets += total_rx_packets;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	return cleaned;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
static void e1000_clean_rx_ring(struct e1000_ring *rx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	struct e1000_ps_page *ps_page;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	unsigned int i, j;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	/* Free all the Rx ring sk_buffs */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	for (i = 0; i < rx_ring->count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
		buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
		if (buffer_info->dma) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
			if (adapter->clean_rx == e1000_clean_rx_irq)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
				dma_unmap_single(&pdev->dev, buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
						 adapter->rx_buffer_len,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
						 DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
				dma_unmap_page(&pdev->dev, buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
					       PAGE_SIZE, DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
				dma_unmap_single(&pdev->dev, buffer_info->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
						 adapter->rx_ps_bsize0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
						 DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
			buffer_info->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		if (buffer_info->page) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
			put_page(buffer_info->page);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
			buffer_info->page = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
		if (buffer_info->skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
			dev_kfree_skb(buffer_info->skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
			buffer_info->skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
			ps_page = &buffer_info->ps_pages[j];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
			if (!ps_page->page)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
				       DMA_FROM_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
			ps_page->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
			put_page(ps_page->page);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
			ps_page->page = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	/* there also may be some cached data from a chained receive */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
	if (rx_ring->rx_skb_top) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		dev_kfree_skb(rx_ring->rx_skb_top);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		rx_ring->rx_skb_top = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	/* Zero out the descriptor ring */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	memset(rx_ring->desc, 0, rx_ring->size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
	rx_ring->next_to_clean = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	rx_ring->next_to_use = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	writel(0, rx_ring->head);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
		e1000e_update_rdt_wa(rx_ring, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		writel(0, rx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
static void e1000e_downshift_workaround(struct work_struct *work)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	struct e1000_adapter *adapter = container_of(work,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
						     struct e1000_adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
						     downshift_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	if (test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
 * e1000_intr_msi - Interrupt Handler
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
 * @irq: interrupt number
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
 * @data: pointer to a network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
static irqreturn_t e1000_intr_msi(int __always_unused irq, void *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	struct net_device *netdev = data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	u32 icr = er32(ICR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	/* read ICR disables interrupts using IAM */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	if (icr & E1000_ICR_LSC) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		hw->mac.get_link_status = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		/* ICH8 workaround-- Call gig speed drop workaround on cable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		 * disconnect (LSC) before accessing any PHY registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		    (!(er32(STATUS) & E1000_STATUS_LU)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
			schedule_work(&adapter->downshift_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		/* 80003ES2LAN workaround-- For packet buffer work-around on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		 * link down event; disable receives here in the ISR and reset
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
		 * adapter in watchdog
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
		if (netif_carrier_ok(netdev) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
			/* disable receives */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
			u32 rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
			adapter->flags |= FLAG_RESTART_NOW;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		/* guard against interrupt when we're going down */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	/* Reset on uncorrectable ECC error */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
		u32 pbeccsts = er32(PBECCSTS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
		adapter->corr_errors +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		adapter->uncorr_errors +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
		/* Do the reset outside of interrupt context */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
		schedule_work(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
		/* return immediately since reset is imminent */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
		return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	if (napi_schedule_prep(&adapter->napi)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		adapter->total_tx_bytes = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		adapter->total_tx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		adapter->total_rx_bytes = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		adapter->total_rx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		__napi_schedule(&adapter->napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
 * e1000_intr - Interrupt Handler
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
 * @irq: interrupt number
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
 * @data: pointer to a network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
static irqreturn_t e1000_intr(int __always_unused irq, void *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	struct net_device *netdev = data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
	u32 rctl, icr = er32(ICR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
		return IRQ_NONE;	/* Not our interrupt */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
	 * not set, then the adapter didn't send an interrupt
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	if (!(icr & E1000_ICR_INT_ASSERTED))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		return IRQ_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	/* Interrupt Auto-Mask...upon reading ICR,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	 * interrupts are masked.  No need for the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
	 * IMC write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	if (icr & E1000_ICR_LSC) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		hw->mac.get_link_status = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		/* ICH8 workaround-- Call gig speed drop workaround on cable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		 * disconnect (LSC) before accessing any PHY registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
		    (!(er32(STATUS) & E1000_STATUS_LU)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
			schedule_work(&adapter->downshift_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
		/* 80003ES2LAN workaround--
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		 * For packet buffer work-around on link down event;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		 * disable receives here in the ISR and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		 * reset adapter in watchdog
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
		if (netif_carrier_ok(netdev) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
			/* disable receives */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
			rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
			adapter->flags |= FLAG_RESTART_NOW;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
		/* guard against interrupt when we're going down */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
		if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	/* Reset on uncorrectable ECC error */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	if ((icr & E1000_ICR_ECCER) && (hw->mac.type == e1000_pch_lpt)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
		u32 pbeccsts = er32(PBECCSTS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		adapter->corr_errors +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		adapter->uncorr_errors +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		/* Do the reset outside of interrupt context */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
		schedule_work(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
		/* return immediately since reset is imminent */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	if (napi_schedule_prep(&adapter->napi)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
		adapter->total_tx_bytes = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
		adapter->total_tx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		adapter->total_rx_bytes = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		adapter->total_rx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
		__napi_schedule(&adapter->napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	struct net_device *netdev = data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
	u32 icr = er32(ICR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
		if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
			ew32(IMS, E1000_IMS_OTHER);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
		return IRQ_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	if (icr & adapter->eiac_mask)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
		ew32(ICS, (icr & adapter->eiac_mask));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	if (icr & E1000_ICR_OTHER) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
		if (!(icr & E1000_ICR_LSC))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
			goto no_link_interrupt;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
		hw->mac.get_link_status = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
		/* guard against interrupt when we're going down */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
		if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
no_link_interrupt:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
	if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
	return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
static irqreturn_t e1000_intr_msix_tx(int __always_unused irq, void *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	struct net_device *netdev = data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
	struct e1000_ring *tx_ring = adapter->tx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	adapter->total_tx_bytes = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
	adapter->total_tx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	if (!e1000_clean_tx_irq(tx_ring))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		/* Ring was not completely cleaned, so fire another interrupt */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		ew32(ICS, tx_ring->ims_val);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
static irqreturn_t e1000_intr_msix_rx(int __always_unused irq, void *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	struct net_device *netdev = data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	struct e1000_ring *rx_ring = adapter->rx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
	/* Write the ITR value calculated at the end of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	 * previous interrupt.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	if (rx_ring->set_itr) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
		writel(1000000000 / (rx_ring->itr_val * 256),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		       rx_ring->itr_register);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
		rx_ring->set_itr = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	if (napi_schedule_prep(&adapter->napi)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		adapter->total_rx_bytes = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		adapter->total_rx_packets = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
		__napi_schedule(&adapter->napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
	return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
 * e1000_configure_msix - Configure MSI-X hardware
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
 * e1000_configure_msix sets up the hardware to properly
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
 * generate MSI-X interrupts.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
static void e1000_configure_msix(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	struct e1000_ring *rx_ring = adapter->rx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
	struct e1000_ring *tx_ring = adapter->tx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
	int vector = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	u32 ctrl_ext, ivar = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	adapter->eiac_mask = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	if (hw->mac.type == e1000_82574) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
		u32 rfctl = er32(RFCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		rfctl |= E1000_RFCTL_ACK_DIS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
		ew32(RFCTL, rfctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	/* Configure Rx vector */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	rx_ring->ims_val = E1000_IMS_RXQ0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	adapter->eiac_mask |= rx_ring->ims_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	if (rx_ring->itr_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
		writel(1000000000 / (rx_ring->itr_val * 256),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
		       rx_ring->itr_register);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
		writel(1, rx_ring->itr_register);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	/* Configure Tx vector */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
	tx_ring->ims_val = E1000_IMS_TXQ0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	if (tx_ring->itr_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		writel(1000000000 / (tx_ring->itr_val * 256),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
		       tx_ring->itr_register);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		writel(1, tx_ring->itr_register);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
	adapter->eiac_mask |= tx_ring->ims_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
	/* set vector for Other Causes, e.g. link changes */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
	vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	if (rx_ring->itr_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
		writel(1000000000 / (rx_ring->itr_val * 256),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
		       hw->hw_addr + E1000_EITR_82574(vector));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	/* Cause Tx interrupts on every write back */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	ivar |= (1 << 31);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	ew32(IVAR, ivar);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	/* enable MSI-X PBA support */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
	ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	/* Auto-Mask Other interrupts upon ICR read */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
	ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
		pci_disable_msix(adapter->pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		kfree(adapter->msix_entries);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
		adapter->msix_entries = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
		pci_disable_msi(adapter->pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		adapter->flags &= ~FLAG_MSI_ENABLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
 * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
 * Attempt to configure interrupts using the best available
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
 * capabilities of the hardware and kernel.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	int err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
	switch (adapter->int_mode) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	case E1000E_INT_MODE_MSIX:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
		if (adapter->flags & FLAG_HAS_MSIX) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
			adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
			adapter->msix_entries = kcalloc(adapter->num_vectors,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
							sizeof(struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
							       msix_entry),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
							GFP_KERNEL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
			if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
				struct e1000_adapter *a = adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
				for (i = 0; i < adapter->num_vectors; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
					adapter->msix_entries[i].entry = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
				err = pci_enable_msix_range(a->pdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
							    a->msix_entries,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
							    a->num_vectors,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
							    a->num_vectors);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
				if (err > 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
					return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
			/* MSI-X failed, so fall through and try MSI */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
			e_err("Failed to initialize MSI-X interrupts.  Falling back to MSI interrupts.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
			e1000e_reset_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
		adapter->int_mode = E1000E_INT_MODE_MSI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
		/* Fall through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	case E1000E_INT_MODE_MSI:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
		if (!pci_enable_msi(adapter->pdev)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
			adapter->flags |= FLAG_MSI_ENABLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
			e_err("Failed to initialize MSI interrupts.  Falling back to legacy interrupts.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		/* Fall through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	case E1000E_INT_MODE_LEGACY:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		/* Don't do anything; this is the system default */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	/* store the number of vectors being used */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	adapter->num_vectors = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
 * e1000_request_msix - Initialize MSI-X interrupts
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
 * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
 * kernel.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
static int e1000_request_msix(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
	int err = 0, vector = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		snprintf(adapter->rx_ring->name,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
			 sizeof(adapter->rx_ring->name) - 1,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
			 "%s-rx-0", netdev->name);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	err = request_irq(adapter->msix_entries[vector].vector,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
			  netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
		return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	adapter->rx_ring->itr_register = adapter->hw.hw_addr +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	    E1000_EITR_82574(vector);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	adapter->rx_ring->itr_val = adapter->itr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
	vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		snprintf(adapter->tx_ring->name,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
			 sizeof(adapter->tx_ring->name) - 1,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
			 "%s-tx-0", netdev->name);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	err = request_irq(adapter->msix_entries[vector].vector,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
			  netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
		return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	adapter->tx_ring->itr_register = adapter->hw.hw_addr +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	    E1000_EITR_82574(vector);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
	adapter->tx_ring->itr_val = adapter->itr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	err = request_irq(adapter->msix_entries[vector].vector,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			  e1000_msix_other, 0, netdev->name, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	e1000_configure_msix(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
 * e1000_request_irq - initialize interrupts
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
 * Attempts to configure interrupts using the best available
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
 * capabilities of the hardware and kernel.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
static int e1000_request_irq(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	int err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
		err = e1000_request_msix(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		if (!err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
			return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
		/* fall back to MSI */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
		e1000e_reset_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
		adapter->int_mode = E1000E_INT_MODE_MSI;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
		e1000e_set_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	if (adapter->flags & FLAG_MSI_ENABLED) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
				  netdev->name, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
		if (!err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
			return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
		/* fall back to legacy interrupt */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
		e1000e_reset_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
			  netdev->name, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
		e_err("Unable to allocate interrupt, Error: %d\n", err);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
static void e1000_free_irq(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
		int vector = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
		free_irq(adapter->msix_entries[vector].vector, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
		vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
		free_irq(adapter->msix_entries[vector].vector, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
		vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
		/* Other Causes interrupt vector */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
		free_irq(adapter->msix_entries[vector].vector, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
	free_irq(adapter->pdev->irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
 * e1000_irq_disable - Mask off interrupt generation on the NIC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
static void e1000_irq_disable(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	ew32(IMC, ~0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	if (adapter->msix_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
		ew32(EIAC_82574, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		for (i = 0; i < adapter->num_vectors; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
			synchronize_irq(adapter->msix_entries[i].vector);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		synchronize_irq(adapter->pdev->irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
 * e1000_irq_enable - Enable default interrupt generation settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
static void e1000_irq_enable(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	} else if (hw->mac.type == e1000_pch_lpt) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
		ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
		ew32(IMS, IMS_ENABLE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
 * e1000e_get_hw_control - get control of the h/w from f/w
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
 * @adapter: address of board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
 * e1000e_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
 * For ASF and Pass Through versions of f/w this means that
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
 * the driver is loaded. For AMT version (only with 82573)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
 * of the f/w this means that the network i/f is open.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
void e1000e_get_hw_control(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
	u32 ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	u32 swsm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
	/* Let firmware know the driver has taken over */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
		swsm = er32(SWSM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
		ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
 * e1000e_release_hw_control - release control of the h/w to f/w
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
 * @adapter: address of board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
 * e1000e_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
 * For ASF and Pass Through versions of f/w this means that the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 * driver is no longer loaded. For AMT version (only with 82573) i
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
 * of the f/w this means that the network i/f is closed.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
void e1000e_release_hw_control(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	u32 ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	u32 swsm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	/* Let firmware taken over control of h/w */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
		swsm = er32(SWSM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
		ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
 * e1000_alloc_ring_dma - allocate memory for a ring structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
				struct e1000_ring *ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
					GFP_KERNEL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	if (!ring->desc)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
		return -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
 * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
 * @tx_ring: Tx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
 * Return 0 on success, negative on failure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
int e1000e_setup_tx_resources(struct e1000_ring *tx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	int err = -ENOMEM, size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
	size = sizeof(struct e1000_buffer) * tx_ring->count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	tx_ring->buffer_info = vzalloc(size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	if (!tx_ring->buffer_info)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
		goto err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	/* round up to nearest 4K */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	tx_ring->size = ALIGN(tx_ring->size, 4096);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
	err = e1000_alloc_ring_dma(adapter, tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
		goto err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
	tx_ring->next_to_use = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	tx_ring->next_to_clean = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
err:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	vfree(tx_ring->buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
 * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
 * Returns 0 on success, negative on failure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
int e1000e_setup_rx_resources(struct e1000_ring *rx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	int i, size, desc_len, err = -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	size = sizeof(struct e1000_buffer) * rx_ring->count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	rx_ring->buffer_info = vzalloc(size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	if (!rx_ring->buffer_info)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
		goto err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	for (i = 0; i < rx_ring->count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
		buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
						sizeof(struct e1000_ps_page),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
						GFP_KERNEL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		if (!buffer_info->ps_pages)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
			goto err_pages;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
	desc_len = sizeof(union e1000_rx_desc_packet_split);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	/* Round up to nearest 4K */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
	rx_ring->size = rx_ring->count * desc_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	rx_ring->size = ALIGN(rx_ring->size, 4096);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	err = e1000_alloc_ring_dma(adapter, rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		goto err_pages;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
	rx_ring->next_to_clean = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
	rx_ring->next_to_use = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
	rx_ring->rx_skb_top = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
err_pages:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
	for (i = 0; i < rx_ring->count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
		buffer_info = &rx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
		kfree(buffer_info->ps_pages);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
err:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	vfree(rx_ring->buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
	e_err("Unable to allocate memory for the receive descriptor ring\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
 * e1000_clean_tx_ring - Free Tx Buffers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
 * @tx_ring: Tx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
static void e1000_clean_tx_ring(struct e1000_ring *tx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	unsigned long size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	for (i = 0; i < tx_ring->count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
		buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
		e1000_put_txbuf(tx_ring, buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	netdev_reset_queue(adapter->netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	size = sizeof(struct e1000_buffer) * tx_ring->count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
	memset(tx_ring->buffer_info, 0, size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	memset(tx_ring->desc, 0, tx_ring->size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	tx_ring->next_to_use = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
	tx_ring->next_to_clean = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	writel(0, tx_ring->head);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
		e1000e_update_tdt_wa(tx_ring, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
		writel(0, tx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
 * e1000e_free_tx_resources - Free Tx Resources per Queue
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
 * @tx_ring: Tx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
 * Free all transmit software resources
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
void e1000e_free_tx_resources(struct e1000_ring *tx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	e1000_clean_tx_ring(tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
	vfree(tx_ring->buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
	tx_ring->buffer_info = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
			  tx_ring->dma);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	tx_ring->desc = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
 * e1000e_free_rx_resources - Free Rx Resources
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
 * @rx_ring: Rx descriptor ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
 * Free all receive software resources
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
void e1000e_free_rx_resources(struct e1000_ring *rx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	struct e1000_adapter *adapter = rx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	e1000_clean_rx_ring(rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	for (i = 0; i < rx_ring->count; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
		kfree(rx_ring->buffer_info[i].ps_pages);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	vfree(rx_ring->buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
	rx_ring->buffer_info = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
			  rx_ring->dma);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
	rx_ring->desc = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
 * e1000_update_itr - update the dynamic ITR value based on statistics
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
 * @adapter: pointer to adapter
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
 * @itr_setting: current adapter->itr
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
 * @packets: the number of packets during this measurement interval
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
 * @bytes: the number of bytes during this measurement interval
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
 *      Stores a new ITR value based on packets and byte
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
 *      counts during the last interrupt.  The advantage of per interrupt
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
 *      computation is faster updates and more accurate ITR for the current
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
 *      traffic pattern.  Constants in this function were computed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
 *      based on theoretical maximum wire speed and thresholds were set based
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
 *      on testing data as well as attempting to minimize response time
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
 *      while increasing bulk throughput.  This functionality is controlled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
 *      by the InterruptThrottleRate module parameter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
static unsigned int e1000_update_itr(u16 itr_setting, int packets, int bytes)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	unsigned int retval = itr_setting;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	if (packets == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
		return itr_setting;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	switch (itr_setting) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
	case lowest_latency:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
		/* handle TSO and jumbo frames */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		if (bytes / packets > 8000)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
			retval = bulk_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
		else if ((packets < 5) && (bytes > 512))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
			retval = low_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	case low_latency:	/* 50 usec aka 20000 ints/s */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
		if (bytes > 10000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
			/* this if handles the TSO accounting */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
			if (bytes / packets > 8000)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
				retval = bulk_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
			else if ((packets < 10) || ((bytes / packets) > 1200))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
				retval = bulk_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
			else if ((packets > 35))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
				retval = lowest_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		} else if (bytes / packets > 2000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
			retval = bulk_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		} else if (packets <= 2 && bytes < 512) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
			retval = lowest_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	case bulk_latency:	/* 250 usec aka 4000 ints/s */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
		if (bytes > 25000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
			if (packets > 35)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
				retval = low_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
		} else if (bytes < 6000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
			retval = low_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	return retval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
static void e1000_set_itr(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	u16 current_itr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
	u32 new_itr = adapter->itr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
	if (adapter->link_speed != SPEED_1000) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		current_itr = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
		new_itr = 4000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		goto set_itr_now;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	if (adapter->flags2 & FLAG2_DISABLE_AIM) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
		new_itr = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
		goto set_itr_now;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	adapter->tx_itr = e1000_update_itr(adapter->tx_itr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
					   adapter->total_tx_packets,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
					   adapter->total_tx_bytes);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		adapter->tx_itr = low_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
	adapter->rx_itr = e1000_update_itr(adapter->rx_itr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
					   adapter->total_rx_packets,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
					   adapter->total_rx_bytes);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
		adapter->rx_itr = low_latency;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
	/* counts and packets in update_itr are dependent on these numbers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
	switch (current_itr) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
	case lowest_latency:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
		new_itr = 70000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	case low_latency:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		new_itr = 20000;	/* aka hwitr = ~200 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	case bulk_latency:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		new_itr = 4000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
set_itr_now:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	if (new_itr != adapter->itr) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		/* this attempts to bias the interrupt rate towards Bulk
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
		 * by adding intermediate steps when interrupt rate is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		 * increasing
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		new_itr = new_itr > adapter->itr ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
		    min(adapter->itr + (new_itr >> 2), new_itr) : new_itr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
		adapter->itr = new_itr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
		adapter->rx_ring->itr_val = new_itr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		if (adapter->msix_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
			adapter->rx_ring->set_itr = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
			e1000e_write_itr(adapter, new_itr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
 * e1000e_write_itr - write the ITR value to the appropriate registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
 * @adapter: address of board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
 * @itr: new ITR value to program
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
 * e1000e_write_itr determines if the adapter is in MSI-X mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
 * and, if so, writes the EITR registers with the ITR value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
 * Otherwise, it writes the ITR value into the ITR register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
void e1000e_write_itr(struct e1000_adapter *adapter, u32 itr)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	u32 new_itr = itr ? 1000000000 / (itr * 256) : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
		int vector;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
		for (vector = 0; vector < adapter->num_vectors; vector++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
			writel(new_itr, hw->hw_addr + E1000_EITR_82574(vector));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
		ew32(ITR, new_itr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
 * e1000_alloc_queues - Allocate memory for all rings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
 * @adapter: board private structure to initialize
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
static int e1000_alloc_queues(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	int size = sizeof(struct e1000_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
	adapter->tx_ring = kzalloc(size, GFP_KERNEL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	if (!adapter->tx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
		goto err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	adapter->tx_ring->count = adapter->tx_ring_count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
	adapter->tx_ring->adapter = adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	adapter->rx_ring = kzalloc(size, GFP_KERNEL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	if (!adapter->rx_ring)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		goto err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	adapter->rx_ring->count = adapter->rx_ring_count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	adapter->rx_ring->adapter = adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
err:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	e_err("Unable to allocate memory for queues\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	kfree(adapter->rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	kfree(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	return -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
 * e1000e_poll - NAPI Rx polling callback
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
 * @napi: struct associated with this polling callback
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
 * @weight: number of packets driver is allowed to process this poll
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
static int e1000e_poll(struct napi_struct *napi, int weight)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
						     napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	struct net_device *poll_dev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	int tx_cleaned = 1, work_done = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	adapter = netdev_priv(poll_dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	if (!adapter->msix_entries ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	    (adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
	adapter->clean_rx(adapter->rx_ring, &work_done, weight);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	if (!tx_cleaned)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		work_done = weight;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	/* If weight not fully consumed, exit the polling mode */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	if (work_done < weight) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		if (adapter->itr_setting & 3)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
			e1000_set_itr(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		napi_complete(napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
			if (adapter->msix_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
				ew32(IMS, adapter->rx_ring->ims_val);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
				e1000_irq_enable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
	return work_done;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
static int e1000_vlan_rx_add_vid(struct net_device *netdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
				 __always_unused __be16 proto, u16 vid)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	u32 vfta, index;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
	/* don't update vlan cookie if already programmed */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
	if ((adapter->hw.mng_cookie.status &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	    (vid == adapter->mng_vlan_id))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
	/* add VID to filter table */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
		index = (vid >> 5) & 0x7F;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		vfta |= (1 << (vid & 0x1F));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
		hw->mac.ops.write_vfta(hw, index, vfta);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	set_bit(vid, adapter->active_vlans);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
static int e1000_vlan_rx_kill_vid(struct net_device *netdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
				  __always_unused __be16 proto, u16 vid)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	u32 vfta, index;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	if ((adapter->hw.mng_cookie.status &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
	    (vid == adapter->mng_vlan_id)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		/* release control to f/w */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
		e1000e_release_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	/* remove VID from filter table */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
		index = (vid >> 5) & 0x7F;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
		vfta &= ~(1 << (vid & 0x1F));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
		hw->mac.ops.write_vfta(hw, index, vfta);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
	clear_bit(vid, adapter->active_vlans);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
 * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
 * @adapter: board private structure to initialize
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
	u32 rctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		/* disable VLAN receive filtering */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
		ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
			e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
					       adapter->mng_vlan_id);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
 * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
 * @adapter: board private structure to initialize
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	u32 rctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		/* enable VLAN receive filtering */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
		rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		rctl |= E1000_RCTL_VFE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
		rctl &= ~E1000_RCTL_CFIEN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
		ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
 * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
 * @adapter: board private structure to initialize
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	/* disable VLAN tag insert/strip */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	ctrl &= ~E1000_CTRL_VME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
 * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
 * @adapter: board private structure to initialize
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
	/* enable VLAN tag insert/strip */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	ctrl |= E1000_CTRL_VME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
	u16 vid = adapter->hw.mng_cookie.vlan_id;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
	u16 old_vid = adapter->mng_vlan_id;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
	if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		e1000_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
		adapter->mng_vlan_id = vid;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q), old_vid);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
static void e1000_restore_vlan(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	u16 vid;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	    e1000_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
	u32 manc, manc2h, mdef, i, j;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	manc = er32(MANC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	/* enable receiving management packets to the host. this will probably
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	 * generate destination unreachable messages from the host OS, but
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	 * the packets will be handled on SMBUS
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	manc |= E1000_MANC_EN_MNG2HOST;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	manc2h = er32(MANC2H);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	switch (hw->mac.type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		manc2h |= (E1000_MANC2H_PORT_623 | E1000_MANC2H_PORT_664);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	case e1000_82574:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	case e1000_82583:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		/* Check if IPMI pass-through decision filter already exists;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		 * if so, enable it.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		for (i = 0, j = 0; i < 8; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
			mdef = er32(MDEF(i));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
			/* Ignore filters with anything other than IPMI ports */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
			if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
				continue;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
			/* Enable this decision filter in MANC2H */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
			if (mdef)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
				manc2h |= (1 << i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
			j |= mdef;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		if (j == (E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		/* Create new decision filter in an empty filter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		for (i = 0, j = 0; i < 8; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
			if (er32(MDEF(i)) == 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
				ew32(MDEF(i), (E1000_MDEF_PORT_623 |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
					       E1000_MDEF_PORT_664));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
				manc2h |= (1 << 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
				j++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		if (!j)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
			e_warn("Unable to create IPMI pass-through filter\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	ew32(MANC2H, manc2h);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	ew32(MANC, manc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
 * e1000_configure_tx - Configure Transmit Unit after Reset
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
 * Configure the Tx unit of the MAC after a reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
static void e1000_configure_tx(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	struct e1000_ring *tx_ring = adapter->tx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
	u64 tdba;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	u32 tdlen, tctl, tarc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	/* Setup the HW Tx Head and Tail descriptor pointers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	tdba = tx_ring->dma;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	ew32(TDBAL(0), (tdba & DMA_BIT_MASK(32)));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	ew32(TDBAH(0), (tdba >> 32));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	ew32(TDLEN(0), tdlen);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	ew32(TDH(0), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	ew32(TDT(0), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	tx_ring->head = adapter->hw.hw_addr + E1000_TDH(0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	tx_ring->tail = adapter->hw.hw_addr + E1000_TDT(0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	/* Set the Tx Interrupt Delay register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	ew32(TIDV, adapter->tx_int_delay);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	/* Tx irq moderation */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	ew32(TADV, adapter->tx_abs_int_delay);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	if (adapter->flags2 & FLAG2_DMA_BURST) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
		u32 txdctl = er32(TXDCTL(0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
		txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
			    E1000_TXDCTL_WTHRESH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		/* set up some performance related parameters to encourage the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		 * hardware to use the bus more efficiently in bursts, depends
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		 * on the tx_int_delay to be enabled,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
		 * wthresh = 1 ==> burst write is disabled to avoid Tx stalls
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
		 * hthresh = 1 ==> prefetch when one or more available
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		 * pthresh = 0x1f ==> prefetch if internal cache 31 or less
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		 * BEWARE: this seems to work but should be considered first if
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
		 * there are Tx hangs or other Tx related bugs
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
		txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
		ew32(TXDCTL(0), txdctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	/* erratum work around: set txdctl the same for both queues */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	ew32(TXDCTL(1), er32(TXDCTL(0)));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	/* Program the Transmit Control Register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
	tctl = er32(TCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
	tctl &= ~E1000_TCTL_CT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
		tarc = er32(TARC(0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
		/* set the speed mode bit, we'll clear it if we're not at
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
		 * gigabit link later
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
#define SPEED_MODE_BIT (1 << 21)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
		tarc |= SPEED_MODE_BIT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
		ew32(TARC(0), tarc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
	/* errata: program both queues to unweighted RR */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
		tarc = er32(TARC(0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
		tarc |= 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
		ew32(TARC(0), tarc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
		tarc = er32(TARC(1));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
		tarc |= 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
		ew32(TARC(1), tarc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	/* Setup Transmit Descriptor Settings for eop descriptor */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
	/* only set IDE if we are delaying interrupts using the timers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
	if (adapter->tx_int_delay)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	/* enable Report Status bit */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	ew32(TCTL, tctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	hw->mac.ops.config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
 * e1000_setup_rctl - configure the receive control registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
 * @adapter: Board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
static void e1000_setup_rctl(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	u32 rctl, rfctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	u32 pages = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
	/* Workaround Si errata on PCHx - configure jumbo frame flow.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	 * If jumbo frames not set, program related MAC/PHY registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	 * to h/w defaults
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	if (hw->mac.type >= e1000_pch2lan) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
		if (adapter->netdev->mtu > ETH_DATA_LEN)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
			e_dbg("failed to enable|disable jumbo frame workaround mode\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	/* Program MC offset vector base */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
	rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	    E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
	    (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	/* Do not Store bad packets */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	rctl &= ~E1000_RCTL_SBP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
	/* Enable Long Packet receive */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
		rctl &= ~E1000_RCTL_LPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		rctl |= E1000_RCTL_LPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	/* Some systems expect that the CRC is included in SMBUS traffic. The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	 * hardware strips the CRC before sending to both SMBUS (BMC) and to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
	 * host memory when this is enabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
		rctl |= E1000_RCTL_SECRC;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
		e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
		phy_data &= 0xfff8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		phy_data |= (1 << 2);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
		e1e_wphy(hw, PHY_REG(770, 26), phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
		e1e_rphy(hw, 22, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
		phy_data &= 0x0fff;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		phy_data |= (1 << 14);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		e1e_wphy(hw, 0x10, 0x2823);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		e1e_wphy(hw, 0x11, 0x0003);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
		e1e_wphy(hw, 22, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	/* Setup buffer sizes */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	rctl &= ~E1000_RCTL_SZ_4096;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	rctl |= E1000_RCTL_BSEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	switch (adapter->rx_buffer_len) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	case 2048:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
		rctl |= E1000_RCTL_SZ_2048;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
		rctl &= ~E1000_RCTL_BSEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	case 4096:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
		rctl |= E1000_RCTL_SZ_4096;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
	case 8192:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
		rctl |= E1000_RCTL_SZ_8192;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	case 16384:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
		rctl |= E1000_RCTL_SZ_16384;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	/* Enable Extended Status in all Receive Descriptors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
	rfctl = er32(RFCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
	rfctl |= E1000_RFCTL_EXTEN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	ew32(RFCTL, rfctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	/* 82571 and greater support packet-split where the protocol
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	 * header is placed in skb->data and the packet data is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	 * In the case of a non-split, skb->data is linearly filled,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	 * followed by the page buffers.  Therefore, skb->data is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	 * sized to hold the largest protocol header.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	 * allocations using alloc_page take too long for regular MTU
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
	 * so only enable packet split for jumbo frames
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	 * Using pages when the page size is greater than 16k wastes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	 * a lot of memory, since we allocate 3 pages at all times
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	 * per packet.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
		adapter->rx_ps_pages = pages;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
		adapter->rx_ps_pages = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	if (adapter->rx_ps_pages) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
		u32 psrctl = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
		/* Enable Packet split descriptors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
		rctl |= E1000_RCTL_DTYP_PS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
		psrctl |= adapter->rx_ps_bsize0 >> E1000_PSRCTL_BSIZE0_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
		switch (adapter->rx_ps_pages) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
		case 3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
			psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE3_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
			/* fall-through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		case 2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
			psrctl |= PAGE_SIZE << E1000_PSRCTL_BSIZE2_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
			/* fall-through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		case 1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
			psrctl |= PAGE_SIZE >> E1000_PSRCTL_BSIZE1_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		ew32(PSRCTL, psrctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	/* This is useful for sniffing bad packets. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
	if (adapter->netdev->features & NETIF_F_RXALL) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		/* UPE and MPE will be handled by normal PROMISC logic
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		 * in e1000e_set_rx_mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		rctl |= (E1000_RCTL_SBP |	/* Receive bad packets */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
			 E1000_RCTL_BAM |	/* RX All Bcast Pkts */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
			 E1000_RCTL_PMCF);	/* RX All MAC Ctrl Pkts */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
		rctl &= ~(E1000_RCTL_VFE |	/* Disable VLAN filter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
			  E1000_RCTL_DPF |	/* Allow filtered pause */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
			  E1000_RCTL_CFIEN);	/* Dis VLAN CFIEN Filter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		/* Do not mess with E1000_CTRL_VME, it affects transmit as well,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
		 * and that breaks VLANs.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
	/* just started the receive unit, no need to restart */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	adapter->flags &= ~FLAG_RESTART_NOW;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
 * e1000_configure_rx - Configure Receive Unit after Reset
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
 * Configure the Rx unit of the MAC after a reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
static void e1000_configure_rx(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	struct e1000_ring *rx_ring = adapter->rx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
	u64 rdba;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	u32 rdlen, rctl, rxcsum, ctrl_ext;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	if (adapter->rx_ps_pages) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		/* this is a 32 byte descriptor */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
		rdlen = rx_ring->count *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
		    sizeof(union e1000_rx_desc_packet_split);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
		adapter->clean_rx = e1000_clean_rx_irq_ps;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
		rdlen = rx_ring->count * sizeof(union e1000_rx_desc_extended);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
		adapter->clean_rx = e1000_clean_rx_irq;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	/* disable receives while setting up the descriptors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	usleep_range(10000, 20000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	if (adapter->flags2 & FLAG2_DMA_BURST) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
		/* set the writeback threshold (only takes effect if the RDTR
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
		 * is set). set GRAN=1 and write back up to 0x4 worth, and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
		 * enable prefetching of 0x20 Rx descriptors
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
		 * granularity = 01
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
		 * wthresh = 04,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
		 * hthresh = 04,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
		 * pthresh = 0x20
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
		ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		/* override the delay timers for enabling bursting, only if
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
		 * the value was not set by the user via module options
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		if (adapter->rx_int_delay == DEFAULT_RDTR)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
			adapter->rx_int_delay = BURST_RDTR;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		if (adapter->rx_abs_int_delay == DEFAULT_RADV)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
			adapter->rx_abs_int_delay = BURST_RADV;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
	/* set the Receive Delay Timer Register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	ew32(RDTR, adapter->rx_int_delay);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	/* irq moderation */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	ew32(RADV, adapter->rx_abs_int_delay);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	if ((adapter->itr_setting != 0) && (adapter->itr != 0))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
		e1000e_write_itr(adapter, adapter->itr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	/* Auto-Mask interrupts upon ICR access */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	ctrl_ext |= E1000_CTRL_EXT_IAME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	ew32(IAM, 0xffffffff);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
	 * the Base and Length of the Rx Descriptor Ring
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
	rdba = rx_ring->dma;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	ew32(RDBAL(0), (rdba & DMA_BIT_MASK(32)));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	ew32(RDBAH(0), (rdba >> 32));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	ew32(RDLEN(0), rdlen);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	ew32(RDH(0), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	ew32(RDT(0), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	rx_ring->head = adapter->hw.hw_addr + E1000_RDH(0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
	rx_ring->tail = adapter->hw.hw_addr + E1000_RDT(0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
	/* Enable Receive Checksum Offload for TCP and UDP */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	rxcsum = er32(RXCSUM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	if (adapter->netdev->features & NETIF_F_RXCSUM)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		rxcsum |= E1000_RXCSUM_TUOFL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		rxcsum &= ~E1000_RXCSUM_TUOFL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
	ew32(RXCSUM, rxcsum);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	/* With jumbo frames, excessive C-state transition latencies result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
	 * in dropped transactions.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
	if (adapter->netdev->mtu > ETH_DATA_LEN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
		u32 lat =
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
		    ((er32(PBA) & E1000_PBA_RXA_MASK) * 1024 -
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
		     adapter->max_frame_size) * 8 / 1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
		if (adapter->flags & FLAG_IS_ICH) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
			u32 rxdctl = er32(RXDCTL(0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
			ew32(RXDCTL(0), rxdctl | 0x3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
		pm_qos_update_request(&adapter->netdev->pm_qos_req, lat);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
		pm_qos_update_request(&adapter->netdev->pm_qos_req,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
				      PM_QOS_DEFAULT_VALUE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	/* Enable Receives */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
 * e1000e_write_mc_addr_list - write multicast addresses to MTA
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
 * Writes multicast address list to the MTA hash table.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
 * Returns: -ENOMEM on failure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
 *                0 on no addresses written
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
 *                X on writing X addresses to MTA
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
static int e1000e_write_mc_addr_list(struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	struct netdev_hw_addr *ha;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	u8 *mta_list;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	if (netdev_mc_empty(netdev)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		/* nothing to program, so clear mc list */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		hw->mac.ops.update_mc_addr_list(hw, NULL, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	mta_list = kzalloc(netdev_mc_count(netdev) * ETH_ALEN, GFP_ATOMIC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	if (!mta_list)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
		return -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	/* update_mc_addr_list expects a packed array of only addresses. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	netdev_for_each_mc_addr(ha, netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	    memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	hw->mac.ops.update_mc_addr_list(hw, mta_list, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	kfree(mta_list);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	return netdev_mc_count(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
 * e1000e_write_uc_addr_list - write unicast addresses to RAR table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
 * Writes unicast address list to the RAR table.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
 * Returns: -ENOMEM on failure/insufficient address space
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
 *                0 on no addresses written
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
 *                X on writing X addresses to the RAR table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
static int e1000e_write_uc_addr_list(struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	unsigned int rar_entries;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	int count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	rar_entries = hw->mac.ops.rar_get_count(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	/* save a rar entry for our hardware address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	rar_entries--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	/* save a rar entry for the LAA workaround */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
		rar_entries--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	/* return ENOMEM indicating insufficient memory for addresses */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	if (netdev_uc_count(netdev) > rar_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		return -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	if (!netdev_uc_empty(netdev) && rar_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
		struct netdev_hw_addr *ha;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
		/* write the addresses in reverse order to avoid write
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
		 * combining
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
		netdev_for_each_uc_addr(ha, netdev) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
			int rval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
			if (!rar_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
			rval = hw->mac.ops.rar_set(hw, ha->addr, rar_entries--);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
			if (rval < 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
				return -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
			count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	/* zero out the remaining RAR entries not used above */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	for (; rar_entries > 0; rar_entries--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
		ew32(RAH(rar_entries), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
		ew32(RAL(rar_entries), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	return count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
 * e1000e_set_rx_mode - secondary unicast, Multicast and Promiscuous mode set
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
 * The ndo_set_rx_mode entry point is called whenever the unicast or multicast
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
 * address list or the network interface flags are updated.  This routine is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
 * responsible for configuring the hardware for proper unicast, multicast,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
 * promiscuous mode, and all-multi behavior.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
static void e1000e_set_rx_mode(struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	u32 rctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	if (pm_runtime_suspended(netdev->dev.parent))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	/* Check for Promiscuous and All Multicast modes */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	/* clear the affected bits */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	if (netdev->flags & IFF_PROMISC) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
		/* Do not hardware filter VLANs in promisc mode */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		e1000e_vlan_filter_disable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
		int count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		if (netdev->flags & IFF_ALLMULTI) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
			rctl |= E1000_RCTL_MPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
			/* Write addresses to the MTA, if the attempt fails
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
			 * then we should just turn on promiscuous mode so
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
			 * that we can at least receive multicast traffic
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
			count = e1000e_write_mc_addr_list(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
			if (count < 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
				rctl |= E1000_RCTL_MPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
		e1000e_vlan_filter_enable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
		/* Write addresses to available RAR registers, if there is not
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
		 * sufficient space to store all the addresses then enable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
		 * unicast promiscuous mode
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
		count = e1000e_write_uc_addr_list(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
		if (count < 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
			rctl |= E1000_RCTL_UPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
		e1000e_vlan_strip_enable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
		e1000e_vlan_strip_disable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
static void e1000e_setup_rss_hash(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	u32 mrqc, rxcsum;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
	int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	static const u32 rsskey[10] = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
		0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	/* Fill out hash function seed */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	for (i = 0; i < 10; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		ew32(RSSRK(i), rsskey[i]);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	/* Direct all traffic to queue 0 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	for (i = 0; i < 32; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		ew32(RETA(i), 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	/* Disable raw packet checksumming so that RSS hash is placed in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	 * descriptor on writeback.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	rxcsum = er32(RXCSUM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	rxcsum |= E1000_RXCSUM_PCSD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	ew32(RXCSUM, rxcsum);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	mrqc = (E1000_MRQC_RSS_FIELD_IPV4 |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
		E1000_MRQC_RSS_FIELD_IPV4_TCP |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
		E1000_MRQC_RSS_FIELD_IPV6 |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
		E1000_MRQC_RSS_FIELD_IPV6_TCP |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
		E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	ew32(MRQC, mrqc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
 * e1000e_get_base_timinca - get default SYSTIM time increment attributes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
 * @timinca: pointer to returned time increment attributes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
 * Get attributes for incrementing the System Time Register SYSTIML/H at
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
 * the default base frequency, and set the cyclecounter shift value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	u32 incvalue, incperiod, shift;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	/* Make sure clock is enabled on I217 before checking the frequency */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	if ((hw->mac.type == e1000_pch_lpt) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	    !(er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_ENABLED) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	    !(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_ENABLED)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
		u32 fextnvm7 = er32(FEXTNVM7);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
		if (!(fextnvm7 & (1 << 0))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
			ew32(FEXTNVM7, fextnvm7 | (1 << 0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
			e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	switch (hw->mac.type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
	case e1000_pch2lan:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
	case e1000_pch_lpt:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
		/* On I217, the clock frequency is 25MHz or 96MHz as
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
		 * indicated by the System Clock Frequency Indication
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
		if ((hw->mac.type != e1000_pch_lpt) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
		    (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
			/* Stable 96MHz frequency */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
			incperiod = INCPERIOD_96MHz;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
			incvalue = INCVALUE_96MHz;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
			shift = INCVALUE_SHIFT_96MHz;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
			adapter->cc.shift = shift + INCPERIOD_SHIFT_96MHz;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
		/* fall-through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	case e1000_82574:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
	case e1000_82583:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		/* Stable 25MHz frequency */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
		incperiod = INCPERIOD_25MHz;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
		incvalue = INCVALUE_25MHz;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
		shift = INCVALUE_SHIFT_25MHz;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		adapter->cc.shift = shift;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
		return -EINVAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	*timinca = ((incperiod << E1000_TIMINCA_INCPERIOD_SHIFT) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		    ((incvalue << shift) & E1000_TIMINCA_INCVALUE_MASK));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
 * e1000e_config_hwtstamp - configure the hwtstamp registers and enable/disable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
 * Outgoing time stamping can be enabled and disabled. Play nice and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
 * disable it when requested, although it shouldn't cause any overhead
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
 * when no packet needs it. At most one packet in the queue may be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
 * marked for time stamping, otherwise it would be impossible to tell
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
 * for sure to which packet the hardware time stamp belongs.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
 * Incoming time stamping has to be configured via the hardware filters.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
 * Not all combinations are supported, in particular event type has to be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
 * specified. Matching the kind of event packet is not supported, with the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
 * exception of "all V2 events regardless of level 2 or 4".
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
static int e1000e_config_hwtstamp(struct e1000_adapter *adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
				  struct hwtstamp_config *config)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	u32 tsync_tx_ctl = E1000_TSYNCTXCTL_ENABLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	u32 tsync_rx_ctl = E1000_TSYNCRXCTL_ENABLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	u32 rxmtrl = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
	u16 rxudp = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	bool is_l4 = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	bool is_l2 = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	u32 regval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
		return -EINVAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	/* flags reserved for future extensions - must be zero */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	if (config->flags)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		return -EINVAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	switch (config->tx_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	case HWTSTAMP_TX_OFF:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		tsync_tx_ctl = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	case HWTSTAMP_TX_ON:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
		return -ERANGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	switch (config->rx_filter) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	case HWTSTAMP_FILTER_NONE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
		tsync_rx_ctl = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		rxmtrl = E1000_RXMTRL_PTP_V1_SYNC_MESSAGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
		is_l4 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L4_V1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
		rxmtrl = E1000_RXMTRL_PTP_V1_DELAY_REQ_MESSAGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
		is_l4 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		/* Also time stamps V2 L2 Path Delay Request/Response */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		is_l2 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
		/* Also time stamps V2 L2 Path Delay Request/Response. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_V2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
		rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
		is_l2 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
		/* Hardware cannot filter just V2 L4 Sync messages;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		 * fall-through to V2 (both L2 and L4) Sync.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
		/* Also time stamps V2 Path Delay Request/Response. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
		rxmtrl = E1000_RXMTRL_PTP_V2_SYNC_MESSAGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		is_l2 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
		is_l4 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
		/* Hardware cannot filter just V2 L4 Delay Request messages;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
		 * fall-through to V2 (both L2 and L4) Delay Request.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
		/* Also time stamps V2 Path Delay Request/Response. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_L2_L4_V2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
		rxmtrl = E1000_RXMTRL_PTP_V2_DELAY_REQ_MESSAGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
		is_l2 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
		is_l4 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
		/* Hardware cannot filter just V2 L4 or L2 Event messages;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		 * fall-through to all V2 (both L2 and L4) Events.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_EVENT_V2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
		is_l2 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
		is_l4 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
		/* For V1, the hardware can only filter Sync messages or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
		 * Delay Request messages but not both so fall-through to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
		 * time stamp all packets.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	case HWTSTAMP_FILTER_ALL:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
		is_l2 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
		is_l4 = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
		tsync_rx_ctl |= E1000_TSYNCRXCTL_TYPE_ALL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
		config->rx_filter = HWTSTAMP_FILTER_ALL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
		return -ERANGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
	adapter->hwtstamp_config = *config;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
	/* enable/disable Tx h/w time stamping */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	regval = er32(TSYNCTXCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
	regval &= ~E1000_TSYNCTXCTL_ENABLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	regval |= tsync_tx_ctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
	ew32(TSYNCTXCTL, regval);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
	if ((er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_ENABLED) !=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	    (regval & E1000_TSYNCTXCTL_ENABLED)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
		e_err("Timesync Tx Control register not set as expected\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
		return -EAGAIN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
	/* enable/disable Rx h/w time stamping */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	regval = er32(TSYNCRXCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	regval &= ~(E1000_TSYNCRXCTL_ENABLED | E1000_TSYNCRXCTL_TYPE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	regval |= tsync_rx_ctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	ew32(TSYNCRXCTL, regval);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	if ((er32(TSYNCRXCTL) & (E1000_TSYNCRXCTL_ENABLED |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
				 E1000_TSYNCRXCTL_TYPE_MASK)) !=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	    (regval & (E1000_TSYNCRXCTL_ENABLED |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
		       E1000_TSYNCRXCTL_TYPE_MASK))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
		e_err("Timesync Rx Control register not set as expected\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
		return -EAGAIN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	/* L2: define ethertype filter for time stamped packets */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	if (is_l2)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
		rxmtrl |= ETH_P_1588;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
	/* define which PTP packets get time stamped */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	ew32(RXMTRL, rxmtrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	/* Filter by destination port */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
	if (is_l4) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
		rxudp = PTP_EV_PORT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
		cpu_to_be16s(&rxudp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	ew32(RXUDP, rxudp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	/* Clear TSYNCRXCTL_VALID & TSYNCTXCTL_VALID bit */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	er32(RXSTMPH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	er32(TXSTMPH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
	/* Get and set the System Time Register SYSTIM base frequency */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
	ret_val = e1000e_get_base_timinca(adapter, &regval);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	ew32(TIMINCA, regval);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
	/* reset the ns time counter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
	timecounter_init(&adapter->tc, &adapter->cc,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
			 ktime_to_ns(ktime_get_real()));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
 * e1000_configure - configure the hardware for Rx and Tx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
 * @adapter: private board structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
static void e1000_configure(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
	struct e1000_ring *rx_ring = adapter->rx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
	e1000e_set_rx_mode(adapter->netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
	e1000_restore_vlan(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	e1000_init_manageability_pt(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	e1000_configure_tx(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
	if (adapter->netdev->features & NETIF_F_RXHASH)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		e1000e_setup_rss_hash(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
	e1000_setup_rctl(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
	e1000_configure_rx(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
	adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
 * e1000e_power_up_phy - restore link in case the phy was powered down
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
 * @adapter: address of board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
 * The phy may be powered down to save power and turn off link when the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
 * driver is unloaded and wake on lan is not enabled (among others)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
 * *** this routine MUST be followed by a call to e1000e_reset ***
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
void e1000e_power_up_phy(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
	if (adapter->hw.phy.ops.power_up)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
		adapter->hw.phy.ops.power_up(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
	adapter->hw.mac.ops.setup_link(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
 * e1000_power_down_phy - Power down the PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
 * Power down the PHY so no link is implied when interface is down.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
 * The PHY cannot be powered down if management or WoL is active.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
static void e1000_power_down_phy(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	if (adapter->hw.phy.ops.power_down)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
		adapter->hw.phy.ops.power_down(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
 * e1000e_reset - bring the hardware into a known good state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
 * This function boots the hardware and enables some settings that
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
 * require a configuration cycle of the hardware - those cannot be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
 * set/changed during runtime. After reset the device needs to be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
 * properly configured for Rx, Tx etc.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
void e1000e_reset(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
	struct e1000_mac_info *mac = &adapter->hw.mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	struct e1000_fc_info *fc = &adapter->hw.fc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	u32 tx_space, min_tx_space, min_rx_space;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	u32 pba = adapter->pba;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	u16 hwm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	/* reset Packet Buffer Allocation to default */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
	ew32(PBA, pba);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
		/* To maintain wire speed transmits, the Tx FIFO should be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		 * large enough to accommodate two full transmit packets,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
		 * the Rx FIFO should be large enough to accommodate at least
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
		 * one full receive packet and is similarly rounded up and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		 * expressed in KB.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
		pba = er32(PBA);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
		/* upper 16 bits has Tx packet buffer allocation size in KB */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		tx_space = pba >> 16;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
		/* lower 16 bits has Rx packet buffer allocation size in KB */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		pba &= 0xffff;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		/* the Tx fifo also stores 16 bytes of information about the Tx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		 * but don't include ethernet FCS because hardware appends it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		min_tx_space = (adapter->max_frame_size +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
				sizeof(struct e1000_tx_desc) - ETH_FCS_LEN) * 2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		min_tx_space = ALIGN(min_tx_space, 1024);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		min_tx_space >>= 10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
		/* software strips receive CRC, so leave room for it */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
		min_rx_space = adapter->max_frame_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
		min_rx_space = ALIGN(min_rx_space, 1024);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		min_rx_space >>= 10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		/* If current Tx allocation is less than the min Tx FIFO size,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		 * and the min Tx FIFO size is less than the current Rx FIFO
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
		 * allocation, take space away from current Rx allocation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
		if ((tx_space < min_tx_space) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
		    ((min_tx_space - tx_space) < pba)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
			pba -= min_tx_space - tx_space;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
			/* if short on Rx space, Rx wins and must trump Tx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
			 * adjustment
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
			if (pba < min_rx_space)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
				pba = min_rx_space;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
		ew32(PBA, pba);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	/* flow control settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	 * The high water mark must be low enough to fit one full frame
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	 * (or the size used for early receive) above it in the Rx FIFO.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	 * Set it to the lower of:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	 * - 90% of the Rx FIFO size, and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	 * - the full Rx FIFO size minus one full frame
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
		fc->pause_time = 0xFFFF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
		fc->pause_time = E1000_FC_PAUSE_TIME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	fc->send_xon = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	fc->current_mode = fc->requested_mode;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	switch (hw->mac.type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
	case e1000_ich9lan:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	case e1000_ich10lan:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
			pba = 14;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
			ew32(PBA, pba);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
			fc->high_water = 0x2800;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
			fc->low_water = fc->high_water - 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
		/* fall-through */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
		hwm = min(((pba << 10) * 9 / 10),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
			  ((pba << 10) - adapter->max_frame_size));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
		fc->high_water = hwm & E1000_FCRTH_RTH;	/* 8-byte granularity */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		fc->low_water = fc->high_water - 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
	case e1000_pchlan:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
		/* Workaround PCH LOM adapter hangs with certain network
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
		 * loads.  If hangs persist, try disabling Tx flow control.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
			fc->high_water = 0x3500;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
			fc->low_water = 0x1500;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
			fc->high_water = 0x5000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
			fc->low_water = 0x3000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		fc->refresh_time = 0x1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	case e1000_pch2lan:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
	case e1000_pch_lpt:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
		fc->refresh_time = 0x0400;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
		if (adapter->netdev->mtu <= ETH_DATA_LEN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
			fc->high_water = 0x05C20;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
			fc->low_water = 0x05048;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
			fc->pause_time = 0x0650;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
		pba = 14;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
		ew32(PBA, pba);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
		fc->high_water = ((pba << 10) * 9 / 10) & E1000_FCRTH_RTH;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
		fc->low_water = ((pba << 10) * 8 / 10) & E1000_FCRTL_RTL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
	/* Alignment of Tx data is on an arbitrary byte boundary with the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
	 * maximum size per Tx descriptor limited only to the transmit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
	 * allocation of the packet buffer minus 96 bytes with an upper
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	 * limit of 24KB due to receive synchronization limitations.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	adapter->tx_fifo_limit = min_t(u32, ((er32(PBA) >> 16) << 10) - 96,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
				       24 << 10);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	/* Disable Adaptive Interrupt Moderation if 2 full packets cannot
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
	 * fit in receive buffer.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
	if (adapter->itr_setting & 0x3) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		if ((adapter->max_frame_size * 2) > (pba << 10)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
			if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
				dev_info(&adapter->pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
					 "Interrupt Throttle Rate off\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
				adapter->flags2 |= FLAG2_DISABLE_AIM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
				e1000e_write_itr(adapter, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
		} else if (adapter->flags2 & FLAG2_DISABLE_AIM) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
			dev_info(&adapter->pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
				 "Interrupt Throttle Rate on\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
			adapter->flags2 &= ~FLAG2_DISABLE_AIM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
			adapter->itr = 20000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
			e1000e_write_itr(adapter, adapter->itr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
	/* Allow time for pending master requests to run */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	mac->ops.reset_hw(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
	/* For parts with AMT enabled, let the firmware know
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	 * that the network interface is in control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	if (adapter->flags & FLAG_HAS_AMT)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
		e1000e_get_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	ew32(WUC, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	if (mac->ops.init_hw(hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
		e_err("Hardware Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	e1000_update_mng_vlan(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	ew32(VET, ETH_P_8021Q);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	e1000e_reset_adaptive(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	/* initialize systim and reset the ns time counter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	e1000e_config_hwtstamp(adapter, &adapter->hwtstamp_config);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	/* Set EEE advertisement as appropriate */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	if (adapter->flags2 & FLAG2_HAS_EEE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
		s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
		u16 adv_addr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
		switch (hw->phy.type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
		case e1000_phy_82579:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
			adv_addr = I82579_EEE_ADVERTISEMENT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
		case e1000_phy_i217:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
			adv_addr = I217_EEE_ADVERTISEMENT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
			dev_err(&adapter->pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
				"Invalid PHY type setting EEE advertisement\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
			return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
		ret_val = hw->phy.ops.acquire(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
			dev_err(&adapter->pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
				"EEE advertisement - unable to acquire PHY\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
			return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
		e1000_write_emi_reg_locked(hw, adv_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
					   hw->dev_spec.ich8lan.eee_disable ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
					   0 : adapter->eee_advert);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		hw->phy.ops.release(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	if (!netif_running(adapter->netdev) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
	    !test_bit(__E1000_TESTING, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		e1000_power_down_phy(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
	e1000_get_phy_info(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
	if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
		u16 phy_data = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
		/* speed up time to link by disabling smart power down, ignore
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
		 * the return value of this function because there is nothing
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
		 * different we would do if it failed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
		phy_data &= ~IGP02E1000_PM_SPD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
int e1000e_up(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
	/* hardware has been reset, we need to reload some things */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
	e1000_configure(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
	clear_bit(__E1000_DOWN, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
	if (adapter->msix_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
		e1000_configure_msix(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
	e1000_irq_enable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
	netif_start_queue(adapter->netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
	/* fire a link change interrupt to start the watchdog */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	if (adapter->msix_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
		ew32(ICS, E1000_ICS_LSC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
static void e1000e_flush_descriptors(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
	if (!(adapter->flags2 & FLAG2_DMA_BURST))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	/* flush pending descriptor writebacks to memory */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	/* execute the writes immediately */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
	/* due to rare timing issues, write to TIDV/RDTR again to ensure the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	 * write is successful
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
	ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	/* execute the writes immediately */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
static void e1000e_update_stats(struct e1000_adapter *adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
 * e1000e_down - quiesce the device and optionally reset the hardware
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
 * @reset: boolean flag to reset the hardware or not
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
void e1000e_down(struct e1000_adapter *adapter, bool reset)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	u32 tctl, rctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
	/* signal that we're down so the interrupt handler does not
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
	 * reschedule our watchdog timer
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
	set_bit(__E1000_DOWN, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
	/* disable receives in the hardware */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
	rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
	/* flush and sleep below */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	netif_stop_queue(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
	/* disable transmits in the hardware */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
	tctl = er32(TCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
	tctl &= ~E1000_TCTL_EN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
	ew32(TCTL, tctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	/* flush both disables and wait for them to finish */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
	usleep_range(10000, 20000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
	e1000_irq_disable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
	napi_synchronize(&adapter->napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
	del_timer_sync(&adapter->watchdog_timer);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
	del_timer_sync(&adapter->phy_info_timer);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	netif_carrier_off(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	spin_lock(&adapter->stats64_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	e1000e_update_stats(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	spin_unlock(&adapter->stats64_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
	e1000e_flush_descriptors(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	e1000_clean_tx_ring(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
	e1000_clean_rx_ring(adapter->rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	adapter->link_speed = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
	adapter->link_duplex = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	/* Disable Si errata workaround on PCHx for jumbo frame flow */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
	if ((hw->mac.type >= e1000_pch2lan) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
	    (adapter->netdev->mtu > ETH_DATA_LEN) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	    e1000_lv_jumbo_workaround_ich8lan(hw, false))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		e_dbg("failed to disable jumbo frame workaround mode\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
	if (reset && !pci_channel_offline(adapter->pdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
void e1000e_reinit_locked(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	might_sleep();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
		usleep_range(1000, 2000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	e1000e_down(adapter, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	e1000e_up(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
	clear_bit(__E1000_RESETTING, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
 * e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
 * @cc: cyclecounter structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
						     cc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	cycle_t systim, systim_next;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
	/* latch SYSTIMH on read of SYSTIML */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	systim = (cycle_t)er32(SYSTIML);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	systim |= (cycle_t)er32(SYSTIMH) << 32;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
	if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
		u64 incvalue, time_delta, rem, temp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
		/* errata for 82574/82583 possible bad bits read from SYSTIMH/L
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
		 * check to see that the time is incrementing at a reasonable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		 * rate and is a multiple of incvalue
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
		incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
		for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
			/* latch SYSTIMH on read of SYSTIML */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
			systim_next = (cycle_t)er32(SYSTIML);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
			systim_next |= (cycle_t)er32(SYSTIMH) << 32;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
			time_delta = systim_next - systim;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
			temp = time_delta;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
			rem = do_div(temp, incvalue);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
			systim = systim_next;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
			if ((time_delta < E1000_82574_SYSTIM_EPSILON) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
			    (rem == 0))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
	return systim;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
 * @adapter: board private structure to initialize
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
 * e1000_sw_init initializes the Adapter private data structure.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
 * Fields are initialized based on PCI device information and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
 * OS network device settings (MTU size).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
static int e1000_sw_init(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
	adapter->rx_ps_bsize0 = 128;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
	adapter->tx_ring_count = E1000_DEFAULT_TXD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	adapter->rx_ring_count = E1000_DEFAULT_RXD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	spin_lock_init(&adapter->stats64_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	e1000e_set_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	if (e1000_alloc_queues(adapter))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
		return -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	/* Setup hardware time stamping cyclecounter */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		adapter->cc.read = e1000e_cyclecounter_read;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
		adapter->cc.mask = CLOCKSOURCE_MASK(64);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		adapter->cc.mult = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
		/* cc.shift set in e1000e_get_base_tininca() */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
		spin_lock_init(&adapter->systim_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
		INIT_WORK(&adapter->tx_hwtstamp_work, e1000e_tx_hwtstamp_work);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
	/* Explicitly disable IRQ since the NIC can be in any state. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
	e1000_irq_disable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
	set_bit(__E1000_DOWN, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
 * e1000_intr_msi_test - Interrupt Handler
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
 * @irq: interrupt number
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
 * @data: pointer to a network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
static irqreturn_t e1000_intr_msi_test(int __always_unused irq, void *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	struct net_device *netdev = data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	u32 icr = er32(ICR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	e_dbg("icr is %08X\n", icr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	if (icr & E1000_ICR_RXSEQ) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
		/* Force memory writes to complete before acknowledging the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
		 * interrupt is handled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
		wmb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
 * e1000_test_msi_interrupt - Returns 0 for successful test
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
 * @adapter: board private struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
 * code flow taken from tg3.c
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	int err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
	/* poll_enable hasn't been called yet, so don't need disable */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
	/* clear any pending events */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	er32(ICR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
	/* free the real vector and request a test handler */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
	e1000_free_irq(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
	e1000e_reset_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
	/* Assume that the test fails, if it succeeds then the test
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	 * MSI irq handler will unset this flag
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
	adapter->flags |= FLAG_MSI_TEST_FAILED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
	err = pci_enable_msi(adapter->pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
		goto msi_test_failed;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
			  netdev->name, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	if (err) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
		pci_disable_msi(adapter->pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
		goto msi_test_failed;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
	/* Force memory writes to complete before enabling and firing an
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
	 * interrupt.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
	wmb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
	e1000_irq_enable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
	/* fire an unusual interrupt on the test handler */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	ew32(ICS, E1000_ICS_RXSEQ);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	msleep(100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
	e1000_irq_disable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
	rmb();			/* read flags after interrupt has been fired */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
		e_info("MSI interrupt test failed, using legacy interrupt.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		e_dbg("MSI interrupt test succeeded!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	free_irq(adapter->pdev->irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
	pci_disable_msi(adapter->pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
msi_test_failed:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
	e1000e_set_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
	return e1000_request_irq(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
 * @adapter: board private struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
 * code flow taken from tg3.c, called with e1000 interrupts disabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
static int e1000_test_msi(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	int err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	u16 pci_cmd;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	if (!(adapter->flags & FLAG_MSI_ENABLED))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	/* disable SERR in case the MSI write causes a master abort */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
	if (pci_cmd & PCI_COMMAND_SERR)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
		pci_write_config_word(adapter->pdev, PCI_COMMAND,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
				      pci_cmd & ~PCI_COMMAND_SERR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
	err = e1000_test_msi_interrupt(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
	/* re-enable SERR */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
	if (pci_cmd & PCI_COMMAND_SERR) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
		pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
		pci_cmd |= PCI_COMMAND_SERR;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
		pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
 * e1000_open - Called when a network interface is made active
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
 * Returns 0 on success, negative value on failure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
 * The open entry point is called when a network interface is made
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
 * active by the system (IFF_UP).  At this point all resources needed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
 * for transmit and receive operations are allocated, the interrupt
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
 * handler is registered with the OS, the watchdog timer is started,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
 * and the stack is notified that the interface is ready.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
static int e1000_open(struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	int err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	/* disallow open during test */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	if (test_bit(__E1000_TESTING, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
		return -EBUSY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	pm_runtime_get_sync(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
	netif_carrier_off(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
	/* allocate transmit descriptors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	err = e1000e_setup_tx_resources(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
		goto err_setup_tx;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
	/* allocate receive descriptors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	err = e1000e_setup_rx_resources(adapter->rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		goto err_setup_rx;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	/* If AMT is enabled, let the firmware know that the network
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
	 * interface is now open and reset the part to a known state.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
	if (adapter->flags & FLAG_HAS_AMT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		e1000e_get_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
		e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	e1000e_power_up_phy(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	if ((adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
		e1000_update_mng_vlan(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	/* DMA latency requirement to workaround jumbo issue */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
	pm_qos_add_request(&adapter->netdev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
			   PM_QOS_DEFAULT_VALUE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
	/* before we allocate an interrupt, we must be ready to handle it.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	 * as soon as we call pci_request_irq, so we have to setup our
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	 * clean_rx handler before we do so.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	e1000_configure(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	err = e1000_request_irq(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
		goto err_req_irq;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	/* Work around PCIe errata with MSI interrupts causing some chipsets to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	 * ignore e1000e MSI messages, which means we need to test our MSI
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	 * interrupt now
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
		err = e1000_test_msi(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		if (err) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
			e_err("Interrupt allocation failed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
			goto err_req_irq;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	/* From here on the code is the same as e1000e_up() */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	clear_bit(__E1000_DOWN, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	napi_enable(&adapter->napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	e1000_irq_enable(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
	adapter->tx_hang_recheck = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	netif_start_queue(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	hw->mac.get_link_status = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	pm_runtime_put(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	/* fire a link status change interrupt to start the watchdog */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	if (adapter->msix_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		ew32(ICS, E1000_ICS_LSC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
err_req_irq:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	e1000e_release_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
	e1000_power_down_phy(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	e1000e_free_rx_resources(adapter->rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
err_setup_rx:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
	e1000e_free_tx_resources(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
err_setup_tx:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
	e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
	pm_runtime_put_sync(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
	return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
 * e1000_close - Disables a network interface
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
 * Returns 0, this is not allowed to fail
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
 * The close entry point is called when an interface is de-activated
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
 * by the OS.  The hardware is still under the drivers control, but
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
 * needs to be disabled.  A global MAC reset is issued to stop the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
 * hardware, and all transmit and receive resources are freed.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
static int e1000_close(struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
	int count = E1000_CHECK_RESET_COUNT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		usleep_range(10000, 20000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	pm_runtime_get_sync(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
	if (!test_bit(__E1000_DOWN, &adapter->state)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
		e1000e_down(adapter, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
		e1000_free_irq(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		/* Link status message must follow this format */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		pr_info("%s NIC Link is Down\n", adapter->netdev->name);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
	napi_disable(&adapter->napi);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
	e1000e_free_tx_resources(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
	e1000e_free_rx_resources(adapter->rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	/* kill manageability vlan ID if supported, but not if a vlan with
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	 * the same ID is registered on the host OS (let 8021q kill it)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
		e1000_vlan_rx_kill_vid(netdev, htons(ETH_P_8021Q),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
				       adapter->mng_vlan_id);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	/* If AMT is enabled, let the firmware know that the network
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	 * interface is now closed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
	if ((adapter->flags & FLAG_HAS_AMT) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
	    !test_bit(__E1000_TESTING, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
		e1000e_release_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	pm_qos_remove_request(&adapter->netdev->pm_qos_req);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	pm_runtime_put_sync(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
 * e1000_set_mac - Change the Ethernet Address of the NIC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
 * @p: pointer to an address structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
 * Returns 0 on success, negative on failure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
static int e1000_set_mac(struct net_device *netdev, void *p)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	struct sockaddr *addr = p;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	if (!is_valid_ether_addr(addr->sa_data))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		return -EADDRNOTAVAIL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
	hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
		/* activate the work around */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
		e1000e_set_laa_state_82571(&adapter->hw, 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		/* Hold a copy of the LAA in RAR[14] This is done so that
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		 * between the time RAR[0] gets clobbered  and the time it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		 * of the RARs and no incoming packets directed to this port
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		 * are dropped. Eventually the LAA will be in RAR[0] and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
		 * RAR[14]
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
				    adapter->hw.mac.rar_entry_count - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
 * e1000e_update_phy_task - work thread to update phy
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
 * @work: pointer to our work struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
 * this worker thread exists because we must acquire a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
 * semaphore to read the phy, which we could msleep while
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
 * waiting for it, and we can't msleep in a timer.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
static void e1000e_update_phy_task(struct work_struct *work)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
	struct e1000_adapter *adapter = container_of(work,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
						     struct e1000_adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
						     update_phy_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	if (test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
	e1000_get_phy_info(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
	/* Enable EEE on 82579 after link up */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	if (hw->phy.type >= e1000_phy_82579)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
		e1000_set_eee_pchlan(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
 * e1000_update_phy_info - timre call-back to update PHY info
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
 * @data: pointer to adapter cast into an unsigned long
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
 * Need to wait a few seconds after link up to get diagnostic information from
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
 * the phy
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
static void e1000_update_phy_info(unsigned long data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	if (test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	schedule_work(&adapter->update_phy_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
 * e1000e_update_phy_stats - Update the PHY statistics counters
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
 * Read/clear the upper 16-bit PHY registers and read/accumulate lower
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
static void e1000e_update_phy_stats(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	ret_val = hw->phy.ops.acquire(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	/* A page set is expensive so check if already on desired page.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	 * If not, set to the page with the PHY status registers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	hw->phy.addr = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
					   &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		goto release;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	if (phy_data != (HV_STATS_PAGE << IGP_PAGE_SHIFT)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
		ret_val = hw->phy.ops.set_page(hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
					       HV_STATS_PAGE << IGP_PAGE_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
			goto release;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	/* Single Collision Count */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	hw->phy.ops.read_reg_page(hw, HV_SCC_UPPER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	ret_val = hw->phy.ops.read_reg_page(hw, HV_SCC_LOWER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
	if (!ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
		adapter->stats.scc += phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	/* Excessive Collision Count */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	hw->phy.ops.read_reg_page(hw, HV_ECOL_UPPER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
	ret_val = hw->phy.ops.read_reg_page(hw, HV_ECOL_LOWER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	if (!ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		adapter->stats.ecol += phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
	/* Multiple Collision Count */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	hw->phy.ops.read_reg_page(hw, HV_MCC_UPPER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
	ret_val = hw->phy.ops.read_reg_page(hw, HV_MCC_LOWER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
	if (!ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
		adapter->stats.mcc += phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	/* Late Collision Count */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
	hw->phy.ops.read_reg_page(hw, HV_LATECOL_UPPER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	ret_val = hw->phy.ops.read_reg_page(hw, HV_LATECOL_LOWER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
	if (!ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
		adapter->stats.latecol += phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	/* Collision Count - also used for adaptive IFS */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	hw->phy.ops.read_reg_page(hw, HV_COLC_UPPER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	ret_val = hw->phy.ops.read_reg_page(hw, HV_COLC_LOWER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
	if (!ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
		hw->mac.collision_delta = phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
	/* Defer Count */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	hw->phy.ops.read_reg_page(hw, HV_DC_UPPER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
	ret_val = hw->phy.ops.read_reg_page(hw, HV_DC_LOWER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
	if (!ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
		adapter->stats.dc += phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
	/* Transmit with no CRS */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	hw->phy.ops.read_reg_page(hw, HV_TNCRS_UPPER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	ret_val = hw->phy.ops.read_reg_page(hw, HV_TNCRS_LOWER, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	if (!ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
		adapter->stats.tncrs += phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
release:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	hw->phy.ops.release(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
 * e1000e_update_stats - Update the board statistics counters
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
static void e1000e_update_stats(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	/* Prevent stats update while adapter is being reset, or if the pci
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	 * connection is down.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	if (adapter->link_speed == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	if (pci_channel_offline(pdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	adapter->stats.crcerrs += er32(CRCERRS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
	adapter->stats.gprc += er32(GPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	adapter->stats.gorc += er32(GORCL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
	er32(GORCH);		/* Clear gorc */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	adapter->stats.bprc += er32(BPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	adapter->stats.mprc += er32(MPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
	adapter->stats.roc += er32(ROC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	adapter->stats.mpc += er32(MPC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	/* Half-duplex statistics */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	if (adapter->link_duplex == HALF_DUPLEX) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
		if (adapter->flags2 & FLAG2_HAS_PHY_STATS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
			e1000e_update_phy_stats(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
			adapter->stats.scc += er32(SCC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
			adapter->stats.ecol += er32(ECOL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
			adapter->stats.mcc += er32(MCC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
			adapter->stats.latecol += er32(LATECOL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
			adapter->stats.dc += er32(DC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
			hw->mac.collision_delta = er32(COLC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
			if ((hw->mac.type != e1000_82574) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
			    (hw->mac.type != e1000_82583))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
				adapter->stats.tncrs += er32(TNCRS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
		adapter->stats.colc += hw->mac.collision_delta;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	adapter->stats.xonrxc += er32(XONRXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	adapter->stats.xontxc += er32(XONTXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	adapter->stats.xoffrxc += er32(XOFFRXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	adapter->stats.xofftxc += er32(XOFFTXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	adapter->stats.gptc += er32(GPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	adapter->stats.gotc += er32(GOTCL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	er32(GOTCH);		/* Clear gotc */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	adapter->stats.rnbc += er32(RNBC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	adapter->stats.ruc += er32(RUC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	adapter->stats.mptc += er32(MPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	adapter->stats.bptc += er32(BPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	/* used for adaptive IFS */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
	hw->mac.tx_packet_delta = er32(TPT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	adapter->stats.tpt += hw->mac.tx_packet_delta;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	adapter->stats.algnerrc += er32(ALGNERRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
	adapter->stats.rxerrc += er32(RXERRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	adapter->stats.cexterr += er32(CEXTERR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
	adapter->stats.tsctc += er32(TSCTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
	adapter->stats.tsctfc += er32(TSCTFC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	/* Fill out the OS statistics structure */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	netdev->stats.multicast = adapter->stats.mprc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
	netdev->stats.collisions = adapter->stats.colc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	/* Rx Errors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	/* RLEC on some newer hardware can be incorrect so build
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	 * our own version based on RUC and ROC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	netdev->stats.rx_errors = adapter->stats.rxerrc +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	    adapter->stats.crcerrs + adapter->stats.algnerrc +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	    adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	netdev->stats.rx_length_errors = adapter->stats.ruc +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	    adapter->stats.roc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	/* Tx Errors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	netdev->stats.tx_errors = adapter->stats.ecol + adapter->stats.latecol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	netdev->stats.tx_window_errors = adapter->stats.latecol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	/* Tx Dropped needs to be maintained elsewhere */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
	/* Management Stats */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
	adapter->stats.mgptc += er32(MGTPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	adapter->stats.mgprc += er32(MGTPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	adapter->stats.mgpdc += er32(MGTPDC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	/* Correctable ECC Errors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	if (hw->mac.type == e1000_pch_lpt) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
		u32 pbeccsts = er32(PBECCSTS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
		adapter->corr_errors +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
		    pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
		adapter->uncorr_errors +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
		    (pbeccsts & E1000_PBECCSTS_UNCORR_ERR_CNT_MASK) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
		    E1000_PBECCSTS_UNCORR_ERR_CNT_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
 * e1000_phy_read_status - Update the PHY register status snapshot
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
 * @adapter: board private structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
static void e1000_phy_read_status(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	struct e1000_phy_regs *phy = &adapter->phy_regs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
	if (!pm_runtime_suspended((&adapter->pdev->dev)->parent) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	    (er32(STATUS) & E1000_STATUS_LU) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
		int ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
		ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
		ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
		ret_val |= e1e_rphy(hw, MII_LPA, &phy->lpa);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
		ret_val |= e1e_rphy(hw, MII_EXPANSION, &phy->expansion);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
		ret_val |= e1e_rphy(hw, MII_CTRL1000, &phy->ctrl1000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
		ret_val |= e1e_rphy(hw, MII_STAT1000, &phy->stat1000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
		ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
			e_warn("Error reading PHY register\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
		/* Do not read PHY registers if link is not up
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
		 * Set values to typical power-on defaults
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
			     BMSR_ERCAP);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
				  ADVERTISE_ALL | ADVERTISE_CSMA);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
		phy->lpa = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
		phy->expansion = EXPANSION_ENABLENPAGE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
		phy->ctrl1000 = ADVERTISE_1000FULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
		phy->stat1000 = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
static void e1000_print_link_info(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
	u32 ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	/* Link status message must follow this format for user tools */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
	pr_info("%s NIC Link is Up %d Mbps %s Duplex, Flow Control: %s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
		adapter->netdev->name, adapter->link_speed,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
		adapter->link_duplex == FULL_DUPLEX ? "Full" : "Half",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
		(ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE) ? "Rx/Tx" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
		(ctrl & E1000_CTRL_RFCE) ? "Rx" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
		(ctrl & E1000_CTRL_TFCE) ? "Tx" : "None");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
static bool e1000e_has_link(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
	bool link_active = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
	s32 ret_val = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
	/* get_link_status is set on LSC (link status) interrupt or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	 * Rx sequence error interrupt.  get_link_status will stay
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
	 * false until the check_for_link establishes link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
	 * for copper adapters ONLY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
	switch (hw->phy.media_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
	case e1000_media_type_copper:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
		if (hw->mac.get_link_status) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
			ret_val = hw->mac.ops.check_for_link(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
			link_active = !hw->mac.get_link_status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
			link_active = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	case e1000_media_type_fiber:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
		ret_val = hw->mac.ops.check_for_link(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	case e1000_media_type_internal_serdes:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
		ret_val = hw->mac.ops.check_for_link(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
		link_active = adapter->hw.mac.serdes_has_link;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
	case e1000_media_type_unknown:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
		e_info("Gigabit has been disabled, downgrading speed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
	return link_active;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
static void e1000e_enable_receives(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
	/* make sure the receive unit is started */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
	    (adapter->flags & FLAG_RESTART_NOW)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
		struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
		u32 rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
		ew32(RCTL, rctl | E1000_RCTL_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
		adapter->flags &= ~FLAG_RESTART_NOW;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
	/* With 82574 controllers, PHY needs to be checked periodically
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
	 * for hung state and reset, if two calls return true
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
	if (e1000_check_phy_82574(hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
		adapter->phy_hang_count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
		adapter->phy_hang_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
	if (adapter->phy_hang_count > 1) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
		adapter->phy_hang_count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
		e_dbg("PHY appears hung - resetting\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
		schedule_work(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
 * e1000_watchdog - Timer Call-back
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
 * @data: pointer to adapter cast into an unsigned long
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
static void e1000_watchdog(unsigned long data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
	/* Do the rest outside of interrupt context */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	schedule_work(&adapter->watchdog_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
	/* TODO: make this use queue_delayed_work() */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
static void e1000_watchdog_task(struct work_struct *work)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
	struct e1000_adapter *adapter = container_of(work,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
						     struct e1000_adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
						     watchdog_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
	struct e1000_mac_info *mac = &adapter->hw.mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	struct e1000_phy_info *phy = &adapter->hw.phy;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
	struct e1000_ring *tx_ring = adapter->tx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
	u32 link, tctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
	if (test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	link = e1000e_has_link(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	if ((netif_carrier_ok(netdev)) && link) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
		/* Cancel scheduled suspend requests. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
		pm_runtime_resume(netdev->dev.parent);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
		e1000e_enable_receives(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		goto link_up;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
		e1000_update_mng_vlan(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	if (link) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
		if (!netif_carrier_ok(netdev)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
			bool txb2b = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
			/* Cancel scheduled suspend requests. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
			pm_runtime_resume(netdev->dev.parent);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
			/* update snapshot of PHY registers on LSC */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
			e1000_phy_read_status(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
			mac->ops.get_link_up_info(&adapter->hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
						  &adapter->link_speed,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
						  &adapter->link_duplex);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
			e1000_print_link_info(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
			/* check if SmartSpeed worked */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
			e1000e_check_downshift(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
			if (phy->speed_downgraded)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
				netdev_warn(netdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
					    "Link Speed was downgraded by SmartSpeed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
			/* On supported PHYs, check for duplex mismatch only
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
			 * if link has autonegotiated at 10/100 half
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
			if ((hw->phy.type == e1000_phy_igp_3 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
			     hw->phy.type == e1000_phy_bm) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
			    hw->mac.autoneg &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
			    (adapter->link_speed == SPEED_10 ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
			     adapter->link_speed == SPEED_100) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
			    (adapter->link_duplex == HALF_DUPLEX)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
				u16 autoneg_exp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
				e1e_rphy(hw, MII_EXPANSION, &autoneg_exp);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
				if (!(autoneg_exp & EXPANSION_NWAY))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
					e_info("Autonegotiated half duplex but link partner cannot autoneg.  Try forcing full duplex if link gets many collisions.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
			/* adjust timeout factor according to speed/duplex */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
			adapter->tx_timeout_factor = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
			switch (adapter->link_speed) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
			case SPEED_10:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
				txb2b = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
				adapter->tx_timeout_factor = 16;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
			case SPEED_100:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
				txb2b = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
				adapter->tx_timeout_factor = 10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
				break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
			/* workaround: re-program speed mode bit after
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
			 * link-up event
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
			    !txb2b) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
				u32 tarc0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
				tarc0 = er32(TARC(0));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
				tarc0 &= ~SPEED_MODE_BIT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
				ew32(TARC(0), tarc0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
			/* disable TSO for pcie and 10/100 speeds, to avoid
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
			 * some hardware issues
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
				switch (adapter->link_speed) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
				case SPEED_10:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
				case SPEED_100:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
					e_info("10/100 speed: disabling TSO\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
					netdev->features &= ~NETIF_F_TSO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
					netdev->features &= ~NETIF_F_TSO6;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
					break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
				case SPEED_1000:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
					netdev->features |= NETIF_F_TSO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
					netdev->features |= NETIF_F_TSO6;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
					break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
				default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
					/* oops */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
					break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
			/* enable transmits in the hardware, need to do this
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
			 * after setting TARC(0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
			tctl = er32(TCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
			tctl |= E1000_TCTL_EN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
			ew32(TCTL, tctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
			/* Perform any post-link-up configuration before
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
			 * reporting link up.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
			if (phy->ops.cfg_on_link_up)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
				phy->ops.cfg_on_link_up(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
			netif_carrier_on(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
			if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
				mod_timer(&adapter->phy_info_timer,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
					  round_jiffies(jiffies + 2 * HZ));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
		if (netif_carrier_ok(netdev)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
			adapter->link_speed = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
			adapter->link_duplex = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
			/* Link status message must follow this format */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
			pr_info("%s NIC Link is Down\n", adapter->netdev->name);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
			netif_carrier_off(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
			if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
				mod_timer(&adapter->phy_info_timer,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
					  round_jiffies(jiffies + 2 * HZ));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
			/* 8000ES2LAN requires a Rx packet buffer work-around
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
			 * on link down event; reset the controller to flush
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
			 * the Rx packet buffer.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
			if (adapter->flags & FLAG_RX_NEEDS_RESTART)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
				adapter->flags |= FLAG_RESTART_NOW;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
				pm_schedule_suspend(netdev->dev.parent,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
						    LINK_TIMEOUT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
link_up:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	spin_lock(&adapter->stats64_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
	e1000e_update_stats(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	adapter->tpt_old = adapter->stats.tpt;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
	adapter->colc_old = adapter->stats.colc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
	adapter->gorc_old = adapter->stats.gorc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
	adapter->gotc_old = adapter->stats.gotc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
	spin_unlock(&adapter->stats64_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
	/* If the link is lost the controller stops DMA, but
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	 * if there is queued Tx work it cannot be done.  So
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
	 * reset the controller to flush the Tx packet buffers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
	if (!netif_carrier_ok(netdev) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
	    (e1000_desc_unused(tx_ring) + 1 < tx_ring->count))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
		adapter->flags |= FLAG_RESTART_NOW;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
	/* If reset is necessary, do it outside of interrupt context. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	if (adapter->flags & FLAG_RESTART_NOW) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
		schedule_work(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
		/* return immediately since reset is imminent */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
	e1000e_update_adaptive(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	/* Simple mode for Interrupt Throttle Rate (ITR) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	if (adapter->itr_setting == 4) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
		/* Symmetric Tx/Rx gets a reduced ITR=2000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
		 * Total asymmetrical Tx or Rx gets ITR=8000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
		 * everyone else is between 2000-8000.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
		u32 goc = (adapter->gotc + adapter->gorc) / 10000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
		u32 dif = (adapter->gotc > adapter->gorc ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
			   adapter->gotc - adapter->gorc :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
			   adapter->gorc - adapter->gotc) / 10000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
		e1000e_write_itr(adapter, itr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	/* Cause software interrupt to ensure Rx ring is cleaned */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
	if (adapter->msix_entries)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
		ew32(ICS, adapter->rx_ring->ims_val);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
		ew32(ICS, E1000_ICS_RXDMT0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
	/* flush pending descriptors to memory before detecting Tx hang */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	e1000e_flush_descriptors(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
	/* Force detection of hung controller every watchdog period */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
	adapter->detect_tx_hung = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
	/* With 82571 controllers, LAA may be overwritten due to controller
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
	 * reset from the other port. Set the appropriate LAA in RAR[0]
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	if (e1000e_get_laa_state_82571(hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
		hw->mac.ops.rar_set(hw, adapter->hw.mac.addr, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
	if (adapter->flags2 & FLAG2_CHECK_PHY_HANG)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
		e1000e_check_82574_phy_workaround(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
	/* Clear valid timestamp stuck in RXSTMPL/H due to a Rx error */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
	if (adapter->hwtstamp_config.rx_filter != HWTSTAMP_FILTER_NONE) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
		if ((adapter->flags2 & FLAG2_CHECK_RX_HWTSTAMP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
		    (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_VALID)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
			er32(RXSTMPH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
			adapter->rx_hwtstamp_cleared++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
			adapter->flags2 |= FLAG2_CHECK_RX_HWTSTAMP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
	/* Reset the timer */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
	if (!test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
		mod_timer(&adapter->watchdog_timer,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
			  round_jiffies(jiffies + 2 * HZ));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
#define E1000_TX_FLAGS_CSUM		0x00000001
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
#define E1000_TX_FLAGS_VLAN		0x00000002
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
#define E1000_TX_FLAGS_TSO		0x00000004
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
#define E1000_TX_FLAGS_IPV4		0x00000008
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
#define E1000_TX_FLAGS_NO_FCS		0x00000010
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
#define E1000_TX_FLAGS_HWTSTAMP		0x00000020
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
#define E1000_TX_FLAGS_VLAN_SHIFT	16
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	struct e1000_context_desc *context_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
	u32 cmd_length = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	u16 ipcse = 0, mss;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
	int err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
	if (!skb_is_gso(skb))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
	err = skb_cow_head(skb, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
	if (err < 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
		return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
	mss = skb_shinfo(skb)->gso_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	if (skb->protocol == htons(ETH_P_IP)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
		struct iphdr *iph = ip_hdr(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
		iph->tot_len = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
		iph->check = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
							 0, IPPROTO_TCP, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
		cmd_length = E1000_TXD_CMD_IP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
		ipcse = skb_transport_offset(skb) - 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
	} else if (skb_is_gso_v6(skb)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
		ipv6_hdr(skb)->payload_len = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
						       &ipv6_hdr(skb)->daddr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
						       0, IPPROTO_TCP, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
		ipcse = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	ipcss = skb_network_offset(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
	tucss = skb_transport_offset(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
		       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
	i = tx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
	context_desc->lower_setup.ip_fields.ipcss = ipcss;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
	context_desc->lower_setup.ip_fields.ipcso = ipcso;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
	context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	context_desc->upper_setup.tcp_fields.tucss = tucss;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
	context_desc->upper_setup.tcp_fields.tucso = tucso;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
	context_desc->upper_setup.tcp_fields.tucse = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
	context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
	buffer_info->time_stamp = jiffies;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
	buffer_info->next_to_watch = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
	i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
	if (i == tx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
		i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	tx_ring->next_to_use = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
	return 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
	struct e1000_context_desc *context_desc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
	u8 css;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
	u32 cmd_len = E1000_TXD_CMD_DEXT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
	__be16 protocol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
	if (skb->ip_summed != CHECKSUM_PARTIAL)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
		return false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
		protocol = skb->protocol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
	switch (protocol) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
	case cpu_to_be16(ETH_P_IP):
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
			cmd_len |= E1000_TXD_CMD_TCP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
	case cpu_to_be16(ETH_P_IPV6):
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
		/* XXX not handling all IPV6 headers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
			cmd_len |= E1000_TXD_CMD_TCP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
		if (unlikely(net_ratelimit()))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
			e_warn("checksum_partial proto=%x!\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
			       be16_to_cpu(protocol));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
	css = skb_checksum_start_offset(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	i = tx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
	buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	context_desc->lower_setup.ip_config = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
	context_desc->upper_setup.tcp_fields.tucss = css;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
	context_desc->upper_setup.tcp_fields.tucse = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
	context_desc->tcp_seg_setup.data = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
	buffer_info->time_stamp = jiffies;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
	buffer_info->next_to_watch = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
	i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
	if (i == tx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
		i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
	tx_ring->next_to_use = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	return true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
			unsigned int first, unsigned int max_per_txd,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
			unsigned int nr_frags)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
	struct pci_dev *pdev = adapter->pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
	unsigned int len = skb_headlen(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
	unsigned int offset = 0, size, count = 0, i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
	unsigned int f, bytecount, segs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
	i = tx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
	while (len) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
		buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
		size = min(len, max_per_txd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
		buffer_info->length = size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
		buffer_info->time_stamp = jiffies;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
		buffer_info->next_to_watch = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
		buffer_info->dma = dma_map_single(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
						  skb->data + offset,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
						  size, DMA_TO_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
		buffer_info->mapped_as_page = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
			goto dma_error;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
		len -= size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
		offset += size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
		count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
		if (len) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
			i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
			if (i == tx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
				i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
	for (f = 0; f < nr_frags; f++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
		const struct skb_frag_struct *frag;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
		frag = &skb_shinfo(skb)->frags[f];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
		len = skb_frag_size(frag);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
		offset = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
		while (len) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
			i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
			if (i == tx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
				i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
			buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
			size = min(len, max_per_txd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
			buffer_info->length = size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
			buffer_info->time_stamp = jiffies;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
			buffer_info->next_to_watch = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
			buffer_info->dma = skb_frag_dma_map(&pdev->dev, frag,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
							    offset, size,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
							    DMA_TO_DEVICE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
			buffer_info->mapped_as_page = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
				goto dma_error;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
			len -= size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
			offset += size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
			count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
	segs = skb_shinfo(skb)->gso_segs ? : 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
	/* multiply data chunks by size of headers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	tx_ring->buffer_info[i].skb = skb;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
	tx_ring->buffer_info[i].segs = segs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
	tx_ring->buffer_info[i].bytecount = bytecount;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
	tx_ring->buffer_info[first].next_to_watch = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
	return count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
dma_error:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
	dev_err(&pdev->dev, "Tx DMA map failed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
	buffer_info->dma = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
	if (count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
		count--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
	while (count--) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
		if (i == 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
			i += tx_ring->count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
		i--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
		buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
		e1000_put_txbuf(tx_ring, buffer_info);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
	struct e1000_tx_desc *tx_desc = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
	struct e1000_buffer *buffer_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
	unsigned int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
	if (tx_flags & E1000_TX_FLAGS_TSO) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
		    E1000_TXD_CMD_TSE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
		if (tx_flags & E1000_TX_FLAGS_IPV4)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
		txd_lower |= E1000_TXD_CMD_VLE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
		txd_lower &= ~(E1000_TXD_CMD_IFCS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
	if (unlikely(tx_flags & E1000_TX_FLAGS_HWTSTAMP)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
		txd_upper |= E1000_TXD_EXTCMD_TSTAMP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
	i = tx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	do {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
		buffer_info = &tx_ring->buffer_info[i];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
		tx_desc = E1000_TX_DESC(*tx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
		tx_desc->lower.data = cpu_to_le32(txd_lower |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
						  buffer_info->length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
		tx_desc->upper.data = cpu_to_le32(txd_upper);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
		i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
		if (i == tx_ring->count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
			i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
	} while (--count > 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
	/* txd_cmd re-enables FCS, so we'll re-disable it here as desired. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
	if (unlikely(tx_flags & E1000_TX_FLAGS_NO_FCS))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
		tx_desc->lower.data &= ~(cpu_to_le32(E1000_TXD_CMD_IFCS));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
	/* Force memory writes to complete before letting h/w
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
	 * know there are new descriptors to fetch.  (Only
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
	 * applicable for weak-ordered memory model archs,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	 * such as IA-64).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
	wmb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
	tx_ring->next_to_use = i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
	if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
		e1000e_update_tdt_wa(tx_ring, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
		writel(i, tx_ring->tail);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
	/* we need this if more than one processor can write to our tail
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
	 * at a time, it synchronizes IO on IA64/Altix systems
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
	mmiowb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
#define MINIMUM_DHCP_PACKET_SIZE 282
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
				    struct sk_buff *skb)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
	u16 length, offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
	if (vlan_tx_tag_present(skb) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
	    !((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
	      (adapter->hw.mng_cookie.status &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
	       E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
	if (((struct ethhdr *)skb->data)->h_proto != htons(ETH_P_IP))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
	{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
		const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data + 14);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
		struct udphdr *udp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
		if (ip->protocol != IPPROTO_UDP)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
			return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
		if (ntohs(udp->dest) != 67)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
			return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
		offset = (u8 *)udp + 8 - skb->data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
		length = skb->len - offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
		return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	struct e1000_adapter *adapter = tx_ring->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
	netif_stop_queue(adapter->netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
	/* Herbert's original patch had:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
	 *  smp_mb__after_netif_stop_queue();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
	 * but since that doesn't exist yet, just open code it.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
	smp_mb();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
	/* We need to check again in a case another CPU has just
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
	 * made room available.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
	if (e1000_desc_unused(tx_ring) < size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
		return -EBUSY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
	/* A reprieve! */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	netif_start_queue(adapter->netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	++adapter->restart_queue;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
	BUG_ON(size > tx_ring->count);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	if (e1000_desc_unused(tx_ring) >= size)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
	return __e1000_maybe_stop_tx(tx_ring, size);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
				    struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	struct e1000_ring *tx_ring = adapter->tx_ring;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
	unsigned int first;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
	unsigned int tx_flags = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
	unsigned int len = skb_headlen(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
	unsigned int nr_frags;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
	unsigned int mss;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
	int count = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
	int tso;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
	unsigned int f;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
	if (test_bit(__E1000_DOWN, &adapter->state)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
		dev_kfree_skb_any(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
		return NETDEV_TX_OK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
	if (skb->len <= 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
		dev_kfree_skb_any(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
		return NETDEV_TX_OK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
	/* The minimum packet size with TCTL.PSP set is 17 bytes so
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
	 * pad skb in order to meet this minimum size requirement
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
	if (unlikely(skb->len < 17)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
		if (skb_pad(skb, 17 - skb->len))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
			return NETDEV_TX_OK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
		skb->len = 17;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
		skb_set_tail_pointer(skb, 17);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
	mss = skb_shinfo(skb)->gso_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
	if (mss) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
		u8 hdr_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
		 * points to just header, pull a few bytes of payload from
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
		 * frags into skb->data
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
		/* we do this workaround for ES2LAN, but it is un-necessary,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
		 * avoiding it could save a lot of cycles
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
		if (skb->data_len && (hdr_len == len)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
			unsigned int pull_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
			pull_size = min_t(unsigned int, 4, skb->data_len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
			if (!__pskb_pull_tail(skb, pull_size)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
				e_err("__pskb_pull_tail failed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
				dev_kfree_skb_any(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
				return NETDEV_TX_OK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
			len = skb_headlen(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
	/* reserve a descriptor for the offload context */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
		count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
	count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
	count += DIV_ROUND_UP(len, adapter->tx_fifo_limit);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
	nr_frags = skb_shinfo(skb)->nr_frags;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
	for (f = 0; f < nr_frags; f++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
		count += DIV_ROUND_UP(skb_frag_size(&skb_shinfo(skb)->frags[f]),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
				      adapter->tx_fifo_limit);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
	if (adapter->hw.mac.tx_pkt_filtering)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
		e1000_transfer_dhcp_info(adapter, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
	/* need: count + 2 desc gap to keep tail from touching
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
	 * head, otherwise try next time
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
	if (e1000_maybe_stop_tx(tx_ring, count + 2))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
		return NETDEV_TX_BUSY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
	if (vlan_tx_tag_present(skb)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
		tx_flags |= E1000_TX_FLAGS_VLAN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
	first = tx_ring->next_to_use;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
	tso = e1000_tso(tx_ring, skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
	if (tso < 0) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
		dev_kfree_skb_any(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
		return NETDEV_TX_OK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
	if (tso)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
		tx_flags |= E1000_TX_FLAGS_TSO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	else if (e1000_tx_csum(tx_ring, skb))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
		tx_flags |= E1000_TX_FLAGS_CSUM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
	 * no longer assume, we must.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
	if (skb->protocol == htons(ETH_P_IP))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
		tx_flags |= E1000_TX_FLAGS_IPV4;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
	if (unlikely(skb->no_fcs))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
		tx_flags |= E1000_TX_FLAGS_NO_FCS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
	/* if count is 0 then mapping error has occurred */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
	count = e1000_tx_map(tx_ring, skb, first, adapter->tx_fifo_limit,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
			     nr_frags);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
	if (count) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
		if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
			     !adapter->tx_hwtstamp_skb)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
			tx_flags |= E1000_TX_FLAGS_HWTSTAMP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
			adapter->tx_hwtstamp_skb = skb_get(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
			adapter->tx_hwtstamp_start = jiffies;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
			schedule_work(&adapter->tx_hwtstamp_work);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
			skb_tx_timestamp(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
		netdev_sent_queue(netdev, skb->len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
		e1000_tx_queue(tx_ring, tx_flags, count);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
		/* Make sure there is space in the ring for the next send. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
		e1000_maybe_stop_tx(tx_ring,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
				    (MAX_SKB_FRAGS *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
				     DIV_ROUND_UP(PAGE_SIZE,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
						  adapter->tx_fifo_limit) + 2));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
		dev_kfree_skb_any(skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
		tx_ring->buffer_info[first].time_stamp = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
		tx_ring->next_to_use = first;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
	return NETDEV_TX_OK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
 * e1000_tx_timeout - Respond to a Tx Hang
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
static void e1000_tx_timeout(struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
	/* Do the reset outside of interrupt context */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
	adapter->tx_timeout_count++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
	schedule_work(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
static void e1000_reset_task(struct work_struct *work)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
	struct e1000_adapter *adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
	adapter = container_of(work, struct e1000_adapter, reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
	/* don't run the task if already down */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
	if (test_bit(__E1000_DOWN, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
	if (!(adapter->flags & FLAG_RESTART_NOW)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
		e1000e_dump(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
		e_err("Reset adapter unexpectedly\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
	e1000e_reinit_locked(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
 * e1000_get_stats64 - Get System Network Statistics
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
 * @stats: rtnl_link_stats64 pointer
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
 * Returns the address of the device statistics structure.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
					     struct rtnl_link_stats64 *stats)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
	memset(stats, 0, sizeof(struct rtnl_link_stats64));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
	spin_lock(&adapter->stats64_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
	e1000e_update_stats(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
	/* Fill out the OS statistics structure */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
	stats->rx_bytes = adapter->stats.gorc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
	stats->rx_packets = adapter->stats.gprc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
	stats->tx_bytes = adapter->stats.gotc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
	stats->tx_packets = adapter->stats.gptc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
	stats->multicast = adapter->stats.mprc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
	stats->collisions = adapter->stats.colc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
	/* Rx Errors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
	/* RLEC on some newer hardware can be incorrect so build
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
	 * our own version based on RUC and ROC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
	stats->rx_errors = adapter->stats.rxerrc +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
	    adapter->stats.crcerrs + adapter->stats.algnerrc +
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
	    adapter->stats.ruc + adapter->stats.roc + adapter->stats.cexterr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
	stats->rx_length_errors = adapter->stats.ruc + adapter->stats.roc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
	stats->rx_crc_errors = adapter->stats.crcerrs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
	stats->rx_frame_errors = adapter->stats.algnerrc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
	stats->rx_missed_errors = adapter->stats.mpc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
	/* Tx Errors */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
	stats->tx_errors = adapter->stats.ecol + adapter->stats.latecol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
	stats->tx_aborted_errors = adapter->stats.ecol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
	stats->tx_window_errors = adapter->stats.latecol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
	stats->tx_carrier_errors = adapter->stats.tncrs;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
	/* Tx Dropped needs to be maintained elsewhere */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
	spin_unlock(&adapter->stats64_lock);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
	return stats;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
 * e1000_change_mtu - Change the Maximum Transfer Unit
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
 * @new_mtu: new value for maximum frame size
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
 * Returns 0 on success, negative on failure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
	int max_frame = new_mtu + VLAN_HLEN + ETH_HLEN + ETH_FCS_LEN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
	/* Jumbo frame support */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
		e_err("Jumbo Frames not supported.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
		return -EINVAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
	/* Supported frame sizes */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
	    (max_frame > adapter->max_hw_frame_size)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
		e_err("Unsupported MTU setting\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
		return -EINVAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
	/* Jumbo frame workaround on 82579 and newer requires CRC be stripped */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
	if ((adapter->hw.mac.type >= e1000_pch2lan) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
	    !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
	    (new_mtu > ETH_DATA_LEN)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
		e_err("Jumbo Frames not supported on this device when CRC stripping is disabled.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
		return -EINVAL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
		usleep_range(1000, 2000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
	adapter->max_frame_size = max_frame;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
	netdev->mtu = new_mtu;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
	pm_runtime_get_sync(netdev->dev.parent);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
	if (netif_running(netdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
		e1000e_down(adapter, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
	 * means we reserve 2 more, this pushes us to allocate from the next
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
	 * larger slab size.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
	 * i.e. RXBUFFER_2048 --> size-4096 slab
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
	 * However with the new *_jumbo_rx* routines, jumbo receives will use
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
	 * fragmented skbs
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
	if (max_frame <= 2048)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
		adapter->rx_buffer_len = 2048;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
		adapter->rx_buffer_len = 4096;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
	/* adjust allocation if LPE protects us, and we aren't using SBP */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
	    (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
		    + ETH_FCS_LEN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
	if (netif_running(netdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
		e1000e_up(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
		e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5821
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5822
	pm_runtime_put_sync(netdev->dev.parent);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5823
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5824
	clear_bit(__E1000_RESETTING, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5825
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5826
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5827
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5828
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5829
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5830
			   int cmd)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5831
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5832
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5833
	struct mii_ioctl_data *data = if_mii(ifr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5834
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5835
	if (adapter->hw.phy.media_type != e1000_media_type_copper)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5836
		return -EOPNOTSUPP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5837
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5838
	switch (cmd) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5839
	case SIOCGMIIPHY:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5840
		data->phy_id = adapter->hw.phy.addr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5841
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5842
	case SIOCGMIIREG:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5843
		e1000_phy_read_status(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5844
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5845
		switch (data->reg_num & 0x1F) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5846
		case MII_BMCR:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5847
			data->val_out = adapter->phy_regs.bmcr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5848
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5849
		case MII_BMSR:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5850
			data->val_out = adapter->phy_regs.bmsr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5851
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5852
		case MII_PHYSID1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5853
			data->val_out = (adapter->hw.phy.id >> 16);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5854
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5855
		case MII_PHYSID2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5856
			data->val_out = (adapter->hw.phy.id & 0xFFFF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5857
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5858
		case MII_ADVERTISE:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5859
			data->val_out = adapter->phy_regs.advertise;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5860
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5861
		case MII_LPA:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5862
			data->val_out = adapter->phy_regs.lpa;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5863
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5864
		case MII_EXPANSION:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5865
			data->val_out = adapter->phy_regs.expansion;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5866
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5867
		case MII_CTRL1000:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5868
			data->val_out = adapter->phy_regs.ctrl1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5869
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5870
		case MII_STAT1000:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5871
			data->val_out = adapter->phy_regs.stat1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5872
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5873
		case MII_ESTATUS:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5874
			data->val_out = adapter->phy_regs.estatus;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5875
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5876
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5877
			return -EIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5878
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5879
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5880
	case SIOCSMIIREG:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5881
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5882
		return -EOPNOTSUPP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5883
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5884
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5885
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5886
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5887
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5888
 * e1000e_hwtstamp_ioctl - control hardware time stamping
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5889
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5890
 * @ifreq: interface request
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5891
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5892
 * Outgoing time stamping can be enabled and disabled. Play nice and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5893
 * disable it when requested, although it shouldn't cause any overhead
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5894
 * when no packet needs it. At most one packet in the queue may be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5895
 * marked for time stamping, otherwise it would be impossible to tell
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5896
 * for sure to which packet the hardware time stamp belongs.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5897
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5898
 * Incoming time stamping has to be configured via the hardware filters.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5899
 * Not all combinations are supported, in particular event type has to be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5900
 * specified. Matching the kind of event packet is not supported, with the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5901
 * exception of "all V2 events regardless of level 2 or 4".
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5902
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5903
static int e1000e_hwtstamp_set(struct net_device *netdev, struct ifreq *ifr)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5904
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5905
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5906
	struct hwtstamp_config config;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5907
	int ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5908
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5909
	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5910
		return -EFAULT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5911
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5912
	ret_val = e1000e_config_hwtstamp(adapter, &config);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5913
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5914
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5915
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5916
	switch (config.rx_filter) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5917
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5918
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5919
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5920
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5921
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5922
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5923
		/* With V2 type filters which specify a Sync or Delay Request,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5924
		 * Path Delay Request/Response messages are also time stamped
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5925
		 * by hardware so notify the caller the requested packets plus
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5926
		 * some others are time stamped.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5927
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5928
		config.rx_filter = HWTSTAMP_FILTER_SOME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5929
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5930
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5931
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5932
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5933
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5934
	return copy_to_user(ifr->ifr_data, &config,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5935
			    sizeof(config)) ? -EFAULT : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5936
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5937
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5938
static int e1000e_hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5939
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5940
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5941
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5942
	return copy_to_user(ifr->ifr_data, &adapter->hwtstamp_config,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5943
			    sizeof(adapter->hwtstamp_config)) ? -EFAULT : 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5944
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5945
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5946
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5947
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5948
	switch (cmd) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5949
	case SIOCGMIIPHY:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5950
	case SIOCGMIIREG:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5951
	case SIOCSMIIREG:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5952
		return e1000_mii_ioctl(netdev, ifr, cmd);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5953
	case SIOCSHWTSTAMP:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5954
		return e1000e_hwtstamp_set(netdev, ifr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5955
	case SIOCGHWTSTAMP:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5956
		return e1000e_hwtstamp_get(netdev, ifr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5957
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5958
		return -EOPNOTSUPP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5959
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5960
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5961
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5962
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5963
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5964
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5965
	u32 i, mac_reg, wuc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5966
	u16 phy_reg, wuc_enable;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5967
	int retval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5968
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5969
	/* copy MAC RARs to PHY RARs */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5970
	e1000_copy_rx_addrs_to_phy_ich8lan(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5971
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5972
	retval = hw->phy.ops.acquire(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5973
	if (retval) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5974
		e_err("Could not acquire PHY\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5975
		return retval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5976
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5977
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5978
	/* Enable access to wakeup registers on and set page to BM_WUC_PAGE */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5979
	retval = e1000_enable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5980
	if (retval)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5981
		goto release;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5982
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5983
	/* copy MAC MTA to PHY MTA - only needed for pchlan */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5984
	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5985
		mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5986
		hw->phy.ops.write_reg_page(hw, BM_MTA(i),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5987
					   (u16)(mac_reg & 0xFFFF));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5988
		hw->phy.ops.write_reg_page(hw, BM_MTA(i) + 1,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5989
					   (u16)((mac_reg >> 16) & 0xFFFF));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5990
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5991
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5992
	/* configure PHY Rx Control register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5993
	hw->phy.ops.read_reg_page(&adapter->hw, BM_RCTL, &phy_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5994
	mac_reg = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5995
	if (mac_reg & E1000_RCTL_UPE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5996
		phy_reg |= BM_RCTL_UPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5997
	if (mac_reg & E1000_RCTL_MPE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5998
		phy_reg |= BM_RCTL_MPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5999
	phy_reg &= ~(BM_RCTL_MO_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6000
	if (mac_reg & E1000_RCTL_MO_3)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6001
		phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6002
			    << BM_RCTL_MO_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6003
	if (mac_reg & E1000_RCTL_BAM)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6004
		phy_reg |= BM_RCTL_BAM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6005
	if (mac_reg & E1000_RCTL_PMCF)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6006
		phy_reg |= BM_RCTL_PMCF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6007
	mac_reg = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6008
	if (mac_reg & E1000_CTRL_RFCE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6009
		phy_reg |= BM_RCTL_RFCE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6010
	hw->phy.ops.write_reg_page(&adapter->hw, BM_RCTL, phy_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6011
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6012
	wuc = E1000_WUC_PME_EN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6013
	if (wufc & (E1000_WUFC_MAG | E1000_WUFC_LNKC))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6014
		wuc |= E1000_WUC_APME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6015
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6016
	/* enable PHY wakeup in MAC register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6017
	ew32(WUFC, wufc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6018
	ew32(WUC, (E1000_WUC_PHY_WAKE | E1000_WUC_APMPME |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6019
		   E1000_WUC_PME_STATUS | wuc));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6020
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6021
	/* configure and enable PHY wakeup in PHY registers */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6022
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUFC, wufc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6023
	hw->phy.ops.write_reg_page(&adapter->hw, BM_WUC, wuc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6024
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6025
	/* activate PHY wakeup */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6026
	wuc_enable |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6027
	retval = e1000_disable_phy_wakeup_reg_access_bm(hw, &wuc_enable);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6028
	if (retval)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6029
		e_err("Could not set PHY Host Wakeup bit\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6030
release:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6031
	hw->phy.ops.release(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6032
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6033
	return retval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6034
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6035
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6036
static int e1000e_pm_freeze(struct device *dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6037
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6038
	struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6039
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6040
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6041
	netif_device_detach(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6042
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6043
	if (netif_running(netdev)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6044
		int count = E1000_CHECK_RESET_COUNT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6045
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6046
		while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6047
			usleep_range(10000, 20000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6048
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6049
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6050
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6051
		/* Quiesce the device without resetting the hardware */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6052
		e1000e_down(adapter, false);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6053
		e1000_free_irq(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6054
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6055
	e1000e_reset_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6056
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6057
	/* Allow time for pending master requests to run */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6058
	e1000e_disable_pcie_master(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6059
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6060
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6061
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6062
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6063
static int __e1000_shutdown(struct pci_dev *pdev, bool runtime)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6064
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6065
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6066
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6067
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6068
	u32 ctrl, ctrl_ext, rctl, status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6069
	/* Runtime suspend should only enable wakeup for link changes */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6070
	u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6071
	int retval = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6072
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6073
	status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6074
	if (status & E1000_STATUS_LU)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6075
		wufc &= ~E1000_WUFC_LNKC;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6076
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6077
	if (wufc) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6078
		e1000_setup_rctl(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6079
		e1000e_set_rx_mode(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6080
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6081
		/* turn on all-multi mode if wake on multicast is enabled */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6082
		if (wufc & E1000_WUFC_MC) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6083
			rctl = er32(RCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6084
			rctl |= E1000_RCTL_MPE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6085
			ew32(RCTL, rctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6086
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6087
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6088
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6089
		ctrl |= E1000_CTRL_ADVD3WUC;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6090
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6091
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6092
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6093
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6094
		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6095
		    adapter->hw.phy.media_type ==
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6096
		    e1000_media_type_internal_serdes) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6097
			/* keep the laser running in D3 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6098
			ctrl_ext = er32(CTRL_EXT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6099
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6100
			ew32(CTRL_EXT, ctrl_ext);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6101
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6102
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6103
		if (!runtime)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6104
			e1000e_power_up_phy(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6105
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6106
		if (adapter->flags & FLAG_IS_ICH)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6107
			e1000_suspend_workarounds_ich8lan(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6108
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6109
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6110
			/* enable wakeup by the PHY */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6111
			retval = e1000_init_phy_wakeup(adapter, wufc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6112
			if (retval)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6113
				return retval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6114
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6115
			/* enable wakeup by the MAC */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6116
			ew32(WUFC, wufc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6117
			ew32(WUC, E1000_WUC_PME_EN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6118
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6119
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6120
		ew32(WUC, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6121
		ew32(WUFC, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6122
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6123
		e1000_power_down_phy(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6124
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6125
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6126
	if (adapter->hw.phy.type == e1000_phy_igp_3) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6127
		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6128
	} else if (hw->mac.type == e1000_pch_lpt) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6129
		if (!(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6130
			/* ULP does not support wake from unicast, multicast
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6131
			 * or broadcast.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6132
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6133
			retval = e1000_enable_ulp_lpt_lp(hw, !runtime);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6134
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6135
		if (retval)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6136
			return retval;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6137
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6138
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6139
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6140
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6141
	 * would have already happened in close and is redundant.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6142
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6143
	e1000e_release_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6144
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6145
	pci_clear_master(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6146
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6147
	/* The pci-e switch on some quad port adapters will report a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6148
	 * correctable error when the MAC transitions from D0 to D3.  To
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6149
	 * prevent this we need to mask off the correctable errors on the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6150
	 * downstream port of the pci-e switch.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6151
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6152
	 * We don't have the associated upstream bridge while assigning
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6153
	 * the PCI device into guest. For example, the KVM on power is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6154
	 * one of the cases.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6155
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6156
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6157
		struct pci_dev *us_dev = pdev->bus->self;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6158
		u16 devctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6159
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6160
		if (!us_dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6161
			return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6162
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6163
		pcie_capability_read_word(us_dev, PCI_EXP_DEVCTL, &devctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6164
		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6165
					   (devctl & ~PCI_EXP_DEVCTL_CERE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6166
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6167
		pci_save_state(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6168
		pci_prepare_to_sleep(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6169
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6170
		pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6171
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6172
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6173
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6174
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6175
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6176
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6177
 * e1000e_disable_aspm - Disable ASPM states
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6178
 * @pdev: pointer to PCI device struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6179
 * @state: bit-mask of ASPM states to disable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6180
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6181
 * Some devices *must* have certain ASPM states disabled per hardware errata.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6182
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6183
static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6184
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6185
	struct pci_dev *parent = pdev->bus->self;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6186
	u16 aspm_dis_mask = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6187
	u16 pdev_aspmc, parent_aspmc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6188
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6189
	switch (state) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6190
	case PCIE_LINK_STATE_L0S:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6191
	case PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6192
		aspm_dis_mask |= PCI_EXP_LNKCTL_ASPM_L0S;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6193
		/* fall-through - can't have L1 without L0s */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6194
	case PCIE_LINK_STATE_L1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6195
		aspm_dis_mask |= PCI_EXP_LNKCTL_ASPM_L1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6196
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6197
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6198
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6199
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6200
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6201
	pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &pdev_aspmc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6202
	pdev_aspmc &= PCI_EXP_LNKCTL_ASPMC;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6203
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6204
	if (parent) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6205
		pcie_capability_read_word(parent, PCI_EXP_LNKCTL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6206
					  &parent_aspmc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6207
		parent_aspmc &= PCI_EXP_LNKCTL_ASPMC;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6208
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6209
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6210
	/* Nothing to do if the ASPM states to be disabled already are */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6211
	if (!(pdev_aspmc & aspm_dis_mask) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6212
	    (!parent || !(parent_aspmc & aspm_dis_mask)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6213
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6214
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6215
	dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6216
		 (aspm_dis_mask & pdev_aspmc & PCI_EXP_LNKCTL_ASPM_L0S) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6217
		 "L0s" : "",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6218
		 (aspm_dis_mask & pdev_aspmc & PCI_EXP_LNKCTL_ASPM_L1) ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6219
		 "L1" : "");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6220
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6221
#ifdef CONFIG_PCIEASPM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6222
	pci_disable_link_state_locked(pdev, state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6223
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6224
	/* Double-check ASPM control.  If not disabled by the above, the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6225
	 * BIOS is preventing that from happening (or CONFIG_PCIEASPM is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6226
	 * not enabled); override by writing PCI config space directly.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6227
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6228
	pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &pdev_aspmc);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6229
	pdev_aspmc &= PCI_EXP_LNKCTL_ASPMC;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6230
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6231
	if (!(aspm_dis_mask & pdev_aspmc))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6232
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6233
#endif
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6234
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6235
	/* Both device and parent should have the same ASPM setting.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6236
	 * Disable ASPM in downstream component first and then upstream.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6237
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6238
	pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, aspm_dis_mask);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6239
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6240
	if (parent)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6241
		pcie_capability_clear_word(parent, PCI_EXP_LNKCTL,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6242
					   aspm_dis_mask);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6243
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6244
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6245
#ifdef CONFIG_PM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6246
static int __e1000_resume(struct pci_dev *pdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6247
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6248
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6249
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6250
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6251
	u16 aspm_disable_flag = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6252
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6253
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6254
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6255
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6256
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6257
	if (aspm_disable_flag)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6258
		e1000e_disable_aspm(pdev, aspm_disable_flag);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6259
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6260
	pci_set_master(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6261
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6262
	if (hw->mac.type >= e1000_pch2lan)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6263
		e1000_resume_workarounds_pchlan(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6264
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6265
	e1000e_power_up_phy(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6266
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6267
	/* report the system wakeup cause from S3/S4 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6268
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6269
		u16 phy_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6270
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6271
		e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6272
		if (phy_data) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6273
			e_info("PHY Wakeup cause - %s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6274
			       phy_data & E1000_WUS_EX ? "Unicast Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6275
			       phy_data & E1000_WUS_MC ? "Multicast Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6276
			       phy_data & E1000_WUS_BC ? "Broadcast Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6277
			       phy_data & E1000_WUS_MAG ? "Magic Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6278
			       phy_data & E1000_WUS_LNKC ?
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6279
			       "Link Status Change" : "other");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6280
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6281
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6282
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6283
		u32 wus = er32(WUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6284
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6285
		if (wus) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6286
			e_info("MAC Wakeup cause - %s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6287
			       wus & E1000_WUS_EX ? "Unicast Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6288
			       wus & E1000_WUS_MC ? "Multicast Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6289
			       wus & E1000_WUS_BC ? "Broadcast Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6290
			       wus & E1000_WUS_MAG ? "Magic Packet" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6291
			       wus & E1000_WUS_LNKC ? "Link Status Change" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6292
			       "other");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6293
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6294
		ew32(WUS, ~0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6295
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6296
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6297
	e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6298
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6299
	e1000_init_manageability_pt(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6300
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6301
	/* If the controller has AMT, do not set DRV_LOAD until the interface
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6302
	 * is up.  For all other cases, let the f/w know that the h/w is now
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6303
	 * under the control of the driver.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6304
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6305
	if (!(adapter->flags & FLAG_HAS_AMT))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6306
		e1000e_get_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6307
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6308
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6309
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6310
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6311
#ifdef CONFIG_PM_SLEEP
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6312
static int e1000e_pm_thaw(struct device *dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6313
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6314
	struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6315
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6316
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6317
	e1000e_set_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6318
	if (netif_running(netdev)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6319
		u32 err = e1000_request_irq(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6320
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6321
		if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6322
			return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6323
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6324
		e1000e_up(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6325
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6326
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6327
	netif_device_attach(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6328
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6329
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6330
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6331
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6332
static int e1000e_pm_suspend(struct device *dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6333
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6334
	struct pci_dev *pdev = to_pci_dev(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6335
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6336
	e1000e_pm_freeze(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6337
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6338
	return __e1000_shutdown(pdev, false);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6339
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6340
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6341
static int e1000e_pm_resume(struct device *dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6342
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6343
	struct pci_dev *pdev = to_pci_dev(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6344
	int rc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6345
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6346
	rc = __e1000_resume(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6347
	if (rc)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6348
		return rc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6349
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6350
	return e1000e_pm_thaw(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6351
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6352
#endif /* CONFIG_PM_SLEEP */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6353
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6354
#ifdef CONFIG_PM_RUNTIME
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6355
static int e1000e_pm_runtime_idle(struct device *dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6356
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6357
	struct pci_dev *pdev = to_pci_dev(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6358
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6359
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6360
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6361
	if (!e1000e_has_link(adapter))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6362
		pm_schedule_suspend(dev, 5 * MSEC_PER_SEC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6363
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6364
	return -EBUSY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6365
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6366
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6367
static int e1000e_pm_runtime_resume(struct device *dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6368
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6369
	struct pci_dev *pdev = to_pci_dev(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6370
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6371
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6372
	int rc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6373
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6374
	rc = __e1000_resume(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6375
	if (rc)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6376
		return rc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6377
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6378
	if (netdev->flags & IFF_UP)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6379
		rc = e1000e_up(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6380
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6381
	return rc;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6382
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6383
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6384
static int e1000e_pm_runtime_suspend(struct device *dev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6385
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6386
	struct pci_dev *pdev = to_pci_dev(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6387
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6388
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6389
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6390
	if (netdev->flags & IFF_UP) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6391
		int count = E1000_CHECK_RESET_COUNT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6392
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6393
		while (test_bit(__E1000_RESETTING, &adapter->state) && count--)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6394
			usleep_range(10000, 20000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6395
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6396
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6397
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6398
		/* Down the device without resetting the hardware */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6399
		e1000e_down(adapter, false);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6400
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6401
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6402
	if (__e1000_shutdown(pdev, true)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6403
		e1000e_pm_runtime_resume(dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6404
		return -EBUSY;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6405
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6406
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6407
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6408
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6409
#endif /* CONFIG_PM_RUNTIME */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6410
#endif /* CONFIG_PM */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6411
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6412
static void e1000_shutdown(struct pci_dev *pdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6413
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6414
	e1000e_pm_freeze(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6415
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6416
	__e1000_shutdown(pdev, false);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6417
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6418
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6419
#ifdef CONFIG_NET_POLL_CONTROLLER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6420
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6421
static irqreturn_t e1000_intr_msix(int __always_unused irq, void *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6422
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6423
	struct net_device *netdev = data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6424
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6425
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6426
	if (adapter->msix_entries) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6427
		int vector, msix_irq;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6428
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6429
		vector = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6430
		msix_irq = adapter->msix_entries[vector].vector;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6431
		disable_irq(msix_irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6432
		e1000_intr_msix_rx(msix_irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6433
		enable_irq(msix_irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6434
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6435
		vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6436
		msix_irq = adapter->msix_entries[vector].vector;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6437
		disable_irq(msix_irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6438
		e1000_intr_msix_tx(msix_irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6439
		enable_irq(msix_irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6440
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6441
		vector++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6442
		msix_irq = adapter->msix_entries[vector].vector;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6443
		disable_irq(msix_irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6444
		e1000_msix_other(msix_irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6445
		enable_irq(msix_irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6446
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6447
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6448
	return IRQ_HANDLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6449
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6450
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6451
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6452
 * e1000_netpoll
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6453
 * @netdev: network interface device structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6454
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6455
 * Polling 'interrupt' - used by things like netconsole to send skbs
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6456
 * without having to re-enable interrupts. It's not called while
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6457
 * the interrupt routine is executing.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6458
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6459
static void e1000_netpoll(struct net_device *netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6460
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6461
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6462
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6463
	switch (adapter->int_mode) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6464
	case E1000E_INT_MODE_MSIX:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6465
		e1000_intr_msix(adapter->pdev->irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6466
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6467
	case E1000E_INT_MODE_MSI:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6468
		disable_irq(adapter->pdev->irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6469
		e1000_intr_msi(adapter->pdev->irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6470
		enable_irq(adapter->pdev->irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6471
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6472
	default:		/* E1000E_INT_MODE_LEGACY */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6473
		disable_irq(adapter->pdev->irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6474
		e1000_intr(adapter->pdev->irq, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6475
		enable_irq(adapter->pdev->irq);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6476
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6477
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6478
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6479
#endif
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6480
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6481
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6482
 * e1000_io_error_detected - called when PCI error is detected
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6483
 * @pdev: Pointer to PCI device
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6484
 * @state: The current pci connection state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6485
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6486
 * This function is called after a PCI bus error affecting
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6487
 * this device has been detected.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6488
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6489
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6490
						pci_channel_state_t state)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6491
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6492
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6493
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6494
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6495
	netif_device_detach(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6496
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6497
	if (state == pci_channel_io_perm_failure)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6498
		return PCI_ERS_RESULT_DISCONNECT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6499
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6500
	if (netif_running(netdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6501
		e1000e_down(adapter, true);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6502
	pci_disable_device(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6503
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6504
	/* Request a slot slot reset. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6505
	return PCI_ERS_RESULT_NEED_RESET;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6506
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6507
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6508
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6509
 * e1000_io_slot_reset - called after the pci bus has been reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6510
 * @pdev: Pointer to PCI device
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6511
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6512
 * Restart the card from scratch, as if from a cold-boot. Implementation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6513
 * resembles the first-half of the e1000e_pm_resume routine.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6514
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6515
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6516
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6517
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6518
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6519
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6520
	u16 aspm_disable_flag = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6521
	int err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6522
	pci_ers_result_t result;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6523
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6524
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6525
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6526
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6527
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6528
	if (aspm_disable_flag)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6529
		e1000e_disable_aspm(pdev, aspm_disable_flag);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6530
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6531
	err = pci_enable_device_mem(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6532
	if (err) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6533
		dev_err(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6534
			"Cannot re-enable PCI device after reset.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6535
		result = PCI_ERS_RESULT_DISCONNECT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6536
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6537
		pdev->state_saved = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6538
		pci_restore_state(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6539
		pci_set_master(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6540
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6541
		pci_enable_wake(pdev, PCI_D3hot, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6542
		pci_enable_wake(pdev, PCI_D3cold, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6543
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6544
		e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6545
		ew32(WUS, ~0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6546
		result = PCI_ERS_RESULT_RECOVERED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6547
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6548
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6549
	pci_cleanup_aer_uncorrect_error_status(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6550
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6551
	return result;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6552
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6553
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6554
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6555
 * e1000_io_resume - called when traffic can start flowing again.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6556
 * @pdev: Pointer to PCI device
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6557
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6558
 * This callback is called when the error recovery driver tells us that
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6559
 * its OK to resume normal operation. Implementation resembles the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6560
 * second-half of the e1000e_pm_resume routine.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6561
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6562
static void e1000_io_resume(struct pci_dev *pdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6563
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6564
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6565
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6566
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6567
	e1000_init_manageability_pt(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6568
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6569
	if (netif_running(netdev)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6570
		if (e1000e_up(adapter)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6571
			dev_err(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6572
				"can't bring device back up after reset\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6573
			return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6574
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6575
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6576
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6577
	netif_device_attach(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6578
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6579
	/* If the controller has AMT, do not set DRV_LOAD until the interface
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6580
	 * is up.  For all other cases, let the f/w know that the h/w is now
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6581
	 * under the control of the driver.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6582
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6583
	if (!(adapter->flags & FLAG_HAS_AMT))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6584
		e1000e_get_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6585
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6586
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6587
static void e1000_print_device_info(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6588
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6589
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6590
	struct net_device *netdev = adapter->netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6591
	u32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6592
	u8 pba_str[E1000_PBANUM_LENGTH];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6593
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6594
	/* print bus type/speed/width info */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6595
	e_info("(PCI Express:2.5GT/s:%s) %pM\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6596
	       /* bus width */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6597
	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6598
		"Width x1"),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6599
	       /* MAC address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6600
	       netdev->dev_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6601
	e_info("Intel(R) PRO/%s Network Connection\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6602
	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6603
	ret_val = e1000_read_pba_string_generic(hw, pba_str,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6604
						E1000_PBANUM_LENGTH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6605
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6606
		strlcpy((char *)pba_str, "Unknown", sizeof(pba_str));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6607
	e_info("MAC: %d, PHY: %d, PBA No: %s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6608
	       hw->mac.type, hw->phy.type, pba_str);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6609
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6610
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6611
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6612
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6613
	struct e1000_hw *hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6614
	int ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6615
	u16 buf = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6616
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6617
	if (hw->mac.type != e1000_82573)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6618
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6619
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6620
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6621
	le16_to_cpus(&buf);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6622
	if (!ret_val && (!(buf & (1 << 0)))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6623
		/* Deep Smart Power Down (DSPD) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6624
		dev_warn(&adapter->pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6625
			 "Warning: detected DSPD enabled in EEPROM\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6626
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6627
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6628
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6629
static int e1000_set_features(struct net_device *netdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6630
			      netdev_features_t features)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6631
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6632
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6633
	netdev_features_t changed = features ^ netdev->features;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6634
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6635
	if (changed & (NETIF_F_TSO | NETIF_F_TSO6))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6636
		adapter->flags |= FLAG_TSO_FORCE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6637
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6638
	if (!(changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6639
			 NETIF_F_RXCSUM | NETIF_F_RXHASH | NETIF_F_RXFCS |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6640
			 NETIF_F_RXALL)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6641
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6642
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6643
	if (changed & NETIF_F_RXFCS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6644
		if (features & NETIF_F_RXFCS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6645
			adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6646
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6647
			/* We need to take it back to defaults, which might mean
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6648
			 * stripping is still disabled at the adapter level.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6649
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6650
			if (adapter->flags2 & FLAG2_DFLT_CRC_STRIPPING)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6651
				adapter->flags2 |= FLAG2_CRC_STRIPPING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6652
			else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6653
				adapter->flags2 &= ~FLAG2_CRC_STRIPPING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6654
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6655
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6656
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6657
	netdev->features = features;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6658
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6659
	if (netif_running(netdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6660
		e1000e_reinit_locked(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6661
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6662
		e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6663
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6664
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6665
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6666
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6667
static const struct net_device_ops e1000e_netdev_ops = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6668
	.ndo_open		= e1000_open,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6669
	.ndo_stop		= e1000_close,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6670
	.ndo_start_xmit		= e1000_xmit_frame,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6671
	.ndo_get_stats64	= e1000e_get_stats64,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6672
	.ndo_set_rx_mode	= e1000e_set_rx_mode,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6673
	.ndo_set_mac_address	= e1000_set_mac,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6674
	.ndo_change_mtu		= e1000_change_mtu,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6675
	.ndo_do_ioctl		= e1000_ioctl,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6676
	.ndo_tx_timeout		= e1000_tx_timeout,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6677
	.ndo_validate_addr	= eth_validate_addr,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6678
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6679
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6680
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6681
#ifdef CONFIG_NET_POLL_CONTROLLER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6682
	.ndo_poll_controller	= e1000_netpoll,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6683
#endif
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6684
	.ndo_set_features = e1000_set_features,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6685
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6686
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6687
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6688
 * e1000_probe - Device Initialization Routine
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6689
 * @pdev: PCI device information struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6690
 * @ent: entry in e1000_pci_tbl
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6691
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6692
 * Returns 0 on success, negative on failure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6693
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6694
 * e1000_probe initializes an adapter identified by a pci_dev structure.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6695
 * The OS initialization, configuring of the adapter private structure,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6696
 * and a hardware reset occur.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6697
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6698
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6699
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6700
	struct net_device *netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6701
	struct e1000_adapter *adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6702
	struct e1000_hw *hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6703
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6704
	resource_size_t mmio_start, mmio_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6705
	resource_size_t flash_start, flash_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6706
	static int cards_found;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6707
	u16 aspm_disable_flag = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6708
	int bars, i, err, pci_using_dac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6709
	u16 eeprom_data = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6710
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6711
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6712
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6713
		aspm_disable_flag = PCIE_LINK_STATE_L0S;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6714
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6715
		aspm_disable_flag |= PCIE_LINK_STATE_L1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6716
	if (aspm_disable_flag)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6717
		e1000e_disable_aspm(pdev, aspm_disable_flag);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6718
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6719
	err = pci_enable_device_mem(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6720
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6721
		return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6722
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6723
	pci_using_dac = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6724
	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6725
	if (!err) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6726
		pci_using_dac = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6727
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6728
		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6729
		if (err) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6730
			dev_err(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6731
				"No usable DMA configuration, aborting\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6732
			goto err_dma;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6733
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6734
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6735
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6736
	bars = pci_select_bars(pdev, IORESOURCE_MEM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6737
	err = pci_request_selected_regions_exclusive(pdev, bars,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6738
						     e1000e_driver_name);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6739
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6740
		goto err_pci_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6741
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6742
	/* AER (Advanced Error Reporting) hooks */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6743
	pci_enable_pcie_error_reporting(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6744
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6745
	pci_set_master(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6746
	/* PCI config space info */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6747
	err = pci_save_state(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6748
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6749
		goto err_alloc_etherdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6750
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6751
	err = -ENOMEM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6752
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6753
	if (!netdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6754
		goto err_alloc_etherdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6755
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6756
	SET_NETDEV_DEV(netdev, &pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6757
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6758
	netdev->irq = pdev->irq;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6759
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6760
	pci_set_drvdata(pdev, netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6761
	adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6762
	hw = &adapter->hw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6763
	adapter->netdev = netdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6764
	adapter->pdev = pdev;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6765
	adapter->ei = ei;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6766
	adapter->pba = ei->pba;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6767
	adapter->flags = ei->flags;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6768
	adapter->flags2 = ei->flags2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6769
	adapter->hw.adapter = adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6770
	adapter->hw.mac.type = ei->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6771
	adapter->max_hw_frame_size = ei->max_hw_frame_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6772
	adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6773
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6774
	mmio_start = pci_resource_start(pdev, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6775
	mmio_len = pci_resource_len(pdev, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6776
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6777
	err = -EIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6778
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6779
	if (!adapter->hw.hw_addr)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6780
		goto err_ioremap;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6781
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6782
	if ((adapter->flags & FLAG_HAS_FLASH) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6783
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6784
		flash_start = pci_resource_start(pdev, 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6785
		flash_len = pci_resource_len(pdev, 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6786
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6787
		if (!adapter->hw.flash_address)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6788
			goto err_flashmap;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6789
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6790
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6791
	/* Set default EEE advertisement */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6792
	if (adapter->flags2 & FLAG2_HAS_EEE)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6793
		adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6794
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6795
	/* construct the net_device struct */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6796
	netdev->netdev_ops = &e1000e_netdev_ops;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6797
	e1000e_set_ethtool_ops(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6798
	netdev->watchdog_timeo = 5 * HZ;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6799
	netif_napi_add(netdev, &adapter->napi, e1000e_poll, 64);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6800
	strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6801
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6802
	netdev->mem_start = mmio_start;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6803
	netdev->mem_end = mmio_start + mmio_len;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6804
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6805
	adapter->bd_number = cards_found++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6806
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6807
	e1000e_check_options(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6808
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6809
	/* setup adapter struct */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6810
	err = e1000_sw_init(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6811
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6812
		goto err_sw_init;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6813
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6814
	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6815
	memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6816
	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6817
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6818
	err = ei->get_variants(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6819
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6820
		goto err_hw_init;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6821
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6822
	if ((adapter->flags & FLAG_IS_ICH) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6823
	    (adapter->flags & FLAG_READ_ONLY_NVM))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6824
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6825
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6826
	hw->mac.ops.get_bus_info(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6827
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6828
	adapter->hw.phy.autoneg_wait_to_complete = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6829
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6830
	/* Copper options */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6831
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6832
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6833
		adapter->hw.phy.disable_polarity_correction = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6834
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6835
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6836
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6837
	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6838
		dev_info(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6839
			 "PHY reset is blocked due to SOL/IDER session.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6840
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6841
	/* Set initial default active device features */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6842
	netdev->features = (NETIF_F_SG |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6843
			    NETIF_F_HW_VLAN_CTAG_RX |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6844
			    NETIF_F_HW_VLAN_CTAG_TX |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6845
			    NETIF_F_TSO |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6846
			    NETIF_F_TSO6 |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6847
			    NETIF_F_RXHASH |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6848
			    NETIF_F_RXCSUM |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6849
			    NETIF_F_HW_CSUM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6850
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6851
	/* Set user-changeable features (subset of all device features) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6852
	netdev->hw_features = netdev->features;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6853
	netdev->hw_features |= NETIF_F_RXFCS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6854
	netdev->priv_flags |= IFF_SUPP_NOFCS;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6855
	netdev->hw_features |= NETIF_F_RXALL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6856
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6857
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6858
		netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6859
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6860
	netdev->vlan_features |= (NETIF_F_SG |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6861
				  NETIF_F_TSO |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6862
				  NETIF_F_TSO6 |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6863
				  NETIF_F_HW_CSUM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6864
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6865
	netdev->priv_flags |= IFF_UNICAST_FLT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6866
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6867
	if (pci_using_dac) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6868
		netdev->features |= NETIF_F_HIGHDMA;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6869
		netdev->vlan_features |= NETIF_F_HIGHDMA;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6870
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6871
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6872
	if (e1000e_enable_mng_pass_thru(&adapter->hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6873
		adapter->flags |= FLAG_MNG_PT_ENABLED;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6874
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6875
	/* before reading the NVM, reset the controller to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6876
	 * put the device in a known good starting state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6877
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6878
	adapter->hw.mac.ops.reset_hw(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6879
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6880
	/* systems with ASPM and others may see the checksum fail on the first
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6881
	 * attempt. Let's give it a few tries
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6882
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6883
	for (i = 0;; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6884
		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6885
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6886
		if (i == 2) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6887
			dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6888
			err = -EIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6889
			goto err_eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6890
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6891
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6892
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6893
	e1000_eeprom_checks(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6894
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6895
	/* copy the MAC address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6896
	if (e1000e_read_mac_addr(&adapter->hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6897
		dev_err(&pdev->dev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6898
			"NVM Read Error while reading MAC address\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6899
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6900
	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6901
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6902
	if (!is_valid_ether_addr(netdev->dev_addr)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6903
		dev_err(&pdev->dev, "Invalid MAC Address: %pM\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6904
			netdev->dev_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6905
		err = -EIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6906
		goto err_eeprom;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6907
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6908
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6909
	init_timer(&adapter->watchdog_timer);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6910
	adapter->watchdog_timer.function = e1000_watchdog;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6911
	adapter->watchdog_timer.data = (unsigned long)adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6912
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6913
	init_timer(&adapter->phy_info_timer);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6914
	adapter->phy_info_timer.function = e1000_update_phy_info;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6915
	adapter->phy_info_timer.data = (unsigned long)adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6916
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6917
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6918
	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6919
	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6920
	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6921
	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6922
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6923
	/* Initialize link parameters. User can change them with ethtool */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6924
	adapter->hw.mac.autoneg = 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6925
	adapter->fc_autoneg = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6926
	adapter->hw.fc.requested_mode = e1000_fc_default;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6927
	adapter->hw.fc.current_mode = e1000_fc_default;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6928
	adapter->hw.phy.autoneg_advertised = 0x2f;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6929
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6930
	/* Initial Wake on LAN setting - If APM wake is enabled in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6931
	 * the EEPROM, enable the ACPI Magic Packet filter
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6932
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6933
	if (adapter->flags & FLAG_APME_IN_WUC) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6934
		/* APME bit in EEPROM is mapped to WUC.APME */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6935
		eeprom_data = er32(WUC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6936
		eeprom_apme_mask = E1000_WUC_APME;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6937
		if ((hw->mac.type > e1000_ich10lan) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6938
		    (eeprom_data & E1000_WUC_PHY_WAKE))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6939
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6940
	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6941
		if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6942
		    (adapter->hw.bus.func == 1))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6943
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_B,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6944
				       1, &eeprom_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6945
		else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6946
			e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_A,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6947
				       1, &eeprom_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6948
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6949
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6950
	/* fetch WoL from EEPROM */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6951
	if (eeprom_data & eeprom_apme_mask)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6952
		adapter->eeprom_wol |= E1000_WUFC_MAG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6953
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6954
	/* now that we have the eeprom settings, apply the special cases
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6955
	 * where the eeprom may be wrong or the board simply won't support
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6956
	 * wake on lan on a particular port
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6957
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6958
	if (!(adapter->flags & FLAG_HAS_WOL))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6959
		adapter->eeprom_wol = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6960
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6961
	/* initialize the wol settings based on the eeprom settings */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6962
	adapter->wol = adapter->eeprom_wol;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6963
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6964
	/* make sure adapter isn't asleep if manageability is enabled */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6965
	if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6966
	    (hw->mac.ops.check_mng_mode(hw)))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6967
		device_wakeup_enable(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6968
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6969
	/* save off EEPROM version number */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6970
	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6971
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6972
	/* reset the hardware with the new settings */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6973
	e1000e_reset(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6974
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6975
	/* If the controller has AMT, do not set DRV_LOAD until the interface
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6976
	 * is up.  For all other cases, let the f/w know that the h/w is now
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6977
	 * under the control of the driver.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6978
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6979
	if (!(adapter->flags & FLAG_HAS_AMT))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6980
		e1000e_get_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6981
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6982
	strlcpy(netdev->name, "eth%d", sizeof(netdev->name));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6983
	err = register_netdev(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6984
	if (err)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6985
		goto err_register;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6986
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6987
	/* carrier off reporting is important to ethtool even BEFORE open */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6988
	netif_carrier_off(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6989
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6990
	/* init PTP hardware clock */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6991
	e1000e_ptp_init(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6992
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6993
	e1000_print_device_info(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6994
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6995
	if (pci_dev_run_wake(pdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6996
		pm_runtime_put_noidle(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6997
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6998
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6999
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7000
err_register:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7001
	if (!(adapter->flags & FLAG_HAS_AMT))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7002
		e1000e_release_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7003
err_eeprom:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7004
	if (hw->phy.ops.check_reset_block && !hw->phy.ops.check_reset_block(hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7005
		e1000_phy_hw_reset(&adapter->hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7006
err_hw_init:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7007
	kfree(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7008
	kfree(adapter->rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7009
err_sw_init:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7010
	if (adapter->hw.flash_address)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7011
		iounmap(adapter->hw.flash_address);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7012
	e1000e_reset_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7013
err_flashmap:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7014
	iounmap(adapter->hw.hw_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7015
err_ioremap:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7016
	free_netdev(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7017
err_alloc_etherdev:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7018
	pci_release_selected_regions(pdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7019
				     pci_select_bars(pdev, IORESOURCE_MEM));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7020
err_pci_reg:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7021
err_dma:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7022
	pci_disable_device(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7023
	return err;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7024
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7025
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7026
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7027
 * e1000_remove - Device Removal Routine
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7028
 * @pdev: PCI device information struct
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7029
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7030
 * e1000_remove is called by the PCI subsystem to alert the driver
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7031
 * that it should release a PCI device.  The could be caused by a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7032
 * Hot-Plug event, or because the driver is going to be removed from
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7033
 * memory.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7034
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7035
static void e1000_remove(struct pci_dev *pdev)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7036
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7037
	struct net_device *netdev = pci_get_drvdata(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7038
	struct e1000_adapter *adapter = netdev_priv(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7039
	bool down = test_bit(__E1000_DOWN, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7040
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7041
	e1000e_ptp_remove(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7042
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7043
	/* The timers may be rescheduled, so explicitly disable them
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7044
	 * from being rescheduled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7045
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7046
	if (!down)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7047
		set_bit(__E1000_DOWN, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7048
	del_timer_sync(&adapter->watchdog_timer);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7049
	del_timer_sync(&adapter->phy_info_timer);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7050
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7051
	cancel_work_sync(&adapter->reset_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7052
	cancel_work_sync(&adapter->watchdog_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7053
	cancel_work_sync(&adapter->downshift_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7054
	cancel_work_sync(&adapter->update_phy_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7055
	cancel_work_sync(&adapter->print_hang_task);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7056
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7057
	if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7058
		cancel_work_sync(&adapter->tx_hwtstamp_work);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7059
		if (adapter->tx_hwtstamp_skb) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7060
			dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7061
			adapter->tx_hwtstamp_skb = NULL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7062
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7063
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7064
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7065
	/* Don't lie to e1000_close() down the road. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7066
	if (!down)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7067
		clear_bit(__E1000_DOWN, &adapter->state);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7068
	unregister_netdev(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7069
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7070
	if (pci_dev_run_wake(pdev))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7071
		pm_runtime_get_noresume(&pdev->dev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7072
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7073
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7074
	 * would have already happened in close and is redundant.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7075
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7076
	e1000e_release_hw_control(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7077
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7078
	e1000e_reset_interrupt_capability(adapter);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7079
	kfree(adapter->tx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7080
	kfree(adapter->rx_ring);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7081
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7082
	iounmap(adapter->hw.hw_addr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7083
	if (adapter->hw.flash_address)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7084
		iounmap(adapter->hw.flash_address);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7085
	pci_release_selected_regions(pdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7086
				     pci_select_bars(pdev, IORESOURCE_MEM));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7087
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7088
	free_netdev(netdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7089
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7090
	/* AER disable */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7091
	pci_disable_pcie_error_reporting(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7092
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7093
	pci_disable_device(pdev);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7094
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7095
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7096
/* PCI Error Recovery (ERS) */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7097
static const struct pci_error_handlers e1000_err_handler = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7098
	.error_detected = e1000_io_error_detected,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7099
	.slot_reset = e1000_io_slot_reset,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7100
	.resume = e1000_io_resume,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7101
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7102
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7103
static const struct pci_device_id e1000_pci_tbl[] = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7104
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7105
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7106
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7107
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7108
	  board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7109
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7110
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7111
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7112
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7113
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7114
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7115
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7116
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7117
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7118
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7119
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7120
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7121
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7122
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7123
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7124
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7125
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7126
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7127
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7128
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7129
	  board_80003es2lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7130
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7131
	  board_80003es2lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7132
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7133
	  board_80003es2lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7134
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7135
	  board_80003es2lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7136
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7137
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7138
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7139
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7140
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7141
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7142
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7143
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7144
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7145
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7146
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7147
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7148
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7149
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7150
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7151
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7152
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7153
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7154
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7155
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7156
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7157
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7158
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7159
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7160
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7161
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7162
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_V), board_ich10lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7163
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7164
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7165
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7166
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7167
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7168
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7169
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7170
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7171
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7172
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_LM), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7173
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_V), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7174
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_LM), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7175
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_V), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7176
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_LM2), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7177
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_V2), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7178
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_LM3), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7179
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_I218_V3), board_pch_lpt },
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7180
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7181
	{ 0, 0, 0, 0, 0, 0, 0 }	/* terminate list */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7182
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7183
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7184
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7185
static const struct dev_pm_ops e1000_pm_ops = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7186
#ifdef CONFIG_PM_SLEEP
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7187
	.suspend	= e1000e_pm_suspend,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7188
	.resume		= e1000e_pm_resume,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7189
	.freeze		= e1000e_pm_freeze,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7190
	.thaw		= e1000e_pm_thaw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7191
	.poweroff	= e1000e_pm_suspend,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7192
	.restore	= e1000e_pm_resume,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7193
#endif
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7194
	SET_RUNTIME_PM_OPS(e1000e_pm_runtime_suspend, e1000e_pm_runtime_resume,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7195
			   e1000e_pm_runtime_idle)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7196
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7197
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7198
/* PCI Device API Driver */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7199
static struct pci_driver e1000_driver = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7200
	.name     = e1000e_driver_name,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7201
	.id_table = e1000_pci_tbl,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7202
	.probe    = e1000_probe,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7203
	.remove   = e1000_remove,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7204
	.driver   = {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7205
		.pm = &e1000_pm_ops,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7206
	},
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7207
	.shutdown = e1000_shutdown,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7208
	.err_handler = &e1000_err_handler
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7209
};
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7210
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7211
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7212
 * e1000_init_module - Driver Registration Routine
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7213
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7214
 * e1000_init_module is the first routine called when the driver is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7215
 * loaded. All it does is register with the PCI subsystem.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7216
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7217
static int __init e1000_init_module(void)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7218
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7219
	int ret;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7220
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7221
	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7222
		e1000e_driver_version);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7223
	pr_info("Copyright(c) 1999 - 2014 Intel Corporation.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7224
	ret = pci_register_driver(&e1000_driver);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7225
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7226
	return ret;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7227
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7228
module_init(e1000_init_module);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7229
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7230
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7231
 * e1000_exit_module - Driver Exit Cleanup Routine
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7232
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7233
 * e1000_exit_module is called just before the driver is removed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7234
 * from memory.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7235
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7236
static void __exit e1000_exit_module(void)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7237
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7238
	pci_unregister_driver(&e1000_driver);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7239
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7240
module_exit(e1000_exit_module);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7241
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7242
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7243
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7244
MODULE_LICENSE("GPL");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7245
MODULE_VERSION(DRV_VERSION);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7246
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  7247
/* netdev.c */