devices/e1000e/netdev-2.6.37-orig.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 2092 941f2d72f115
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
2092
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2010 Intel Corporation.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/module.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/types.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/init.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/pci.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/vmalloc.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/pagemap.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/delay.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/netdevice.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <linux/tcp.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <linux/ipv6.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <linux/slab.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <net/checksum.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <net/ip6_checksum.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <linux/mii.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <linux/ethtool.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
#include <linux/if_vlan.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include <linux/cpu.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
#include <linux/smp.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#include <linux/pm_qos_params.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
#include <linux/pm_runtime.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#include <linux/aer.h>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
#include "e1000.h"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
#define DRV_EXTRAVERSION "-k2"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
#define DRV_VERSION "1.2.7" DRV_EXTRAVERSION
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
char e1000e_driver_name[] = "e1000e";
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
const char e1000e_driver_version[] = DRV_VERSION;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
static const struct e1000_info *e1000_info_tbl[] = {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	[board_82571]		= &e1000_82571_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	[board_82572]		= &e1000_82572_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	[board_82573]		= &e1000_82573_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	[board_82574]		= &e1000_82574_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	[board_82583]		= &e1000_82583_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	[board_80003es2lan]	= &e1000_es2_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	[board_ich8lan]		= &e1000_ich8_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	[board_ich9lan]		= &e1000_ich9_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	[board_ich10lan]	= &e1000_ich10_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	[board_pchlan]		= &e1000_pch_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	[board_pch2lan]		= &e1000_pch2_info,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
struct e1000_reg_info {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	u32 ofs;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	char *name;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
#define E1000_RDFH	0x02410 /* Rx Data FIFO Head - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
#define E1000_RDFT	0x02418 /* Rx Data FIFO Tail - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
#define E1000_RDFHS	0x02420 /* Rx Data FIFO Head Saved - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
#define E1000_RDFTS	0x02428 /* Rx Data FIFO Tail Saved - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
#define E1000_RDFPC	0x02430 /* Rx Data FIFO Packet Count - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
#define E1000_TDFH	0x03410 /* Tx Data FIFO Head - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
#define E1000_TDFT	0x03418 /* Tx Data FIFO Tail - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
#define E1000_TDFHS	0x03420 /* Tx Data FIFO Head Saved - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
#define E1000_TDFTS	0x03428 /* Tx Data FIFO Tail Saved - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
#define E1000_TDFPC	0x03430 /* Tx Data FIFO Packet Count - RW */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
static const struct e1000_reg_info e1000_reg_info_tbl[] = {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	/* General Registers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	{E1000_CTRL, "CTRL"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	{E1000_STATUS, "STATUS"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	{E1000_CTRL_EXT, "CTRL_EXT"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	/* Interrupt Registers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	{E1000_ICR, "ICR"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	/* RX Registers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	{E1000_RCTL, "RCTL"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	{E1000_RDLEN, "RDLEN"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	{E1000_RDH, "RDH"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	{E1000_RDT, "RDT"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	{E1000_RDTR, "RDTR"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	{E1000_RXDCTL(0), "RXDCTL"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	{E1000_ERT, "ERT"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	{E1000_RDBAL, "RDBAL"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	{E1000_RDBAH, "RDBAH"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	{E1000_RDFH, "RDFH"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	{E1000_RDFT, "RDFT"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	{E1000_RDFHS, "RDFHS"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	{E1000_RDFTS, "RDFTS"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	{E1000_RDFPC, "RDFPC"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	/* TX Registers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	{E1000_TCTL, "TCTL"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	{E1000_TDBAL, "TDBAL"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	{E1000_TDBAH, "TDBAH"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	{E1000_TDLEN, "TDLEN"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	{E1000_TDH, "TDH"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	{E1000_TDT, "TDT"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	{E1000_TIDV, "TIDV"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	{E1000_TXDCTL(0), "TXDCTL"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	{E1000_TADV, "TADV"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
	{E1000_TARC(0), "TARC"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	{E1000_TDFH, "TDFH"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	{E1000_TDFT, "TDFT"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	{E1000_TDFHS, "TDFHS"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	{E1000_TDFTS, "TDFTS"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
	{E1000_TDFPC, "TDFPC"},
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
	/* List Terminator */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
	{}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
 * e1000_regdump - register printout routine
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
	int n = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	char rname[16];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
	u32 regs[8];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
	switch (reginfo->ofs) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
	case E1000_RXDCTL(0):
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
		for (n = 0; n < 2; n++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
			regs[n] = __er32(hw, E1000_RXDCTL(n));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	case E1000_TXDCTL(0):
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
		for (n = 0; n < 2; n++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
			regs[n] = __er32(hw, E1000_TXDCTL(n));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	case E1000_TARC(0):
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
		for (n = 0; n < 2; n++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
			regs[n] = __er32(hw, E1000_TARC(n));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
		printk(KERN_INFO "%-15s %08x\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
			reginfo->name, __er32(hw, reginfo->ofs));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
	snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
	printk(KERN_INFO "%-15s ", rname);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	for (n = 0; n < 2; n++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
		printk(KERN_CONT "%08x ", regs[n]);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
	printk(KERN_CONT "\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
 * e1000e_dump - Print registers, tx-ring and rx-ring
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
static void e1000e_dump(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	struct e1000_reg_info *reginfo;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	struct e1000_tx_desc *tx_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
	struct my_u0 { u64 a; u64 b; } *u0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	union e1000_rx_desc_packet_split *rx_desc_ps;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	struct e1000_rx_desc *rx_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	struct my_u1 { u64 a; u64 b; u64 c; u64 d; } *u1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	u32 staterr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
	int i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	if (!netif_msg_hw(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	/* Print netdevice Info */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	if (netdev) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		dev_info(&adapter->pdev->dev, "Net device Info\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		printk(KERN_INFO "Device Name     state            "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
			"trans_start      last_rx\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		printk(KERN_INFO "%-15s %016lX %016lX %016lX\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
			netdev->name,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
			netdev->state,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
			netdev->trans_start,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
			netdev->last_rx);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	/* Print Registers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	dev_info(&adapter->pdev->dev, "Register Dump\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	printk(KERN_INFO " Register Name   Value\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	     reginfo->name; reginfo++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
		e1000_regdump(hw, reginfo);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	/* Print TX Ring Summary */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	if (!netdev || !netif_running(netdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
		goto exit;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma  ]"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
		" leng ntw timestamp\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
		0, tx_ring->next_to_use, tx_ring->next_to_clean,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
		(unsigned long long)buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
		buffer_info->length,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
		buffer_info->next_to_watch,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
		(unsigned long long)buffer_info->time_stamp);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	/* Print TX Rings */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	if (!netif_msg_tx_done(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
		goto rx_ring_summary;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
	dev_info(&adapter->pdev->dev, "TX Rings Dump\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	 * Legacy Transmit Descriptor
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	 *   +--------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	 *   +--------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	 *   +--------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	 *   63       48 47        36 35    32 31     24 23    16 15        0
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	 *   63      48 47    40 39       32 31             16 15    8 7      0
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	 *   +----------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	 *   +----------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	 *   +----------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	 * Extended Data Descriptor (DTYP=0x1)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	 *   +----------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	 * 0 |                     Buffer Address [63:0]                      |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	 *   +----------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	 *   +----------------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	printk(KERN_INFO "Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen]"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
		" [bi->dma       ] leng  ntw timestamp        bi->skb "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
		"<-- Legacy format\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
	printk(KERN_INFO "Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen]"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		" [bi->dma       ] leng  ntw timestamp        bi->skb "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
		"<-- Ext Context format\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	printk(KERN_INFO "Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen]"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		" [bi->dma       ] leng  ntw timestamp        bi->skb "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
		"<-- Ext Data format\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		tx_desc = E1000_TX_DESC(*tx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		u0 = (struct my_u0 *)tx_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		printk(KERN_INFO "T%c[0x%03X]    %016llX %016llX %016llX "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
			"%04X  %3X %016llX %p",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		       (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
			((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
		       (unsigned long long)le64_to_cpu(u0->a),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		       (unsigned long long)le64_to_cpu(u0->b),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		       (unsigned long long)buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		       buffer_info->length, buffer_info->next_to_watch,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		       (unsigned long long)buffer_info->time_stamp,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
		       buffer_info->skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
			printk(KERN_CONT " NTC/U\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		else if (i == tx_ring->next_to_use)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
			printk(KERN_CONT " NTU\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
		else if (i == tx_ring->next_to_clean)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
			printk(KERN_CONT " NTC\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
			printk(KERN_CONT "\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
		if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
					16, 1, phys_to_virt(buffer_info->dma),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
					buffer_info->length, true);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	/* Print RX Rings Summary */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
rx_ring_summary:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	dev_info(&adapter->pdev->dev, "RX Rings Summary\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
	printk(KERN_INFO "Queue [NTU] [NTC]\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	printk(KERN_INFO " %5d %5X %5X\n", 0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		rx_ring->next_to_use, rx_ring->next_to_clean);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	/* Print RX Rings */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	if (!netif_msg_rx_status(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		goto exit;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	dev_info(&adapter->pdev->dev, "RX Rings Dump\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	switch (adapter->rx_ps_pages) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	case 1:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
	case 2:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	case 3:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		/* [Extended] Packet Split Receive Descriptor Format
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
		 *    +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		 *  0 |                Buffer Address 0 [63:0]              |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		 *    +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
		 *  8 |                Buffer Address 1 [63:0]              |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		 *    +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		 * 16 |                Buffer Address 2 [63:0]              |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
		 *    +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		 * 24 |                Buffer Address 3 [63:0]              |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		 *    +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		printk(KERN_INFO "R  [desc]      [buffer 0 63:0 ] "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
			"[buffer 1 63:0 ] "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		       "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma       ] "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		       "[bi->skb] <-- Ext Pkt Split format\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
		/* [Extended] Receive Descriptor (Write-Back) Format
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		 *   63       48 47    32 31     13 12    8 7    4 3        0
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		 *   +------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		 * 0 | Packet   | IP     |  Rsvd   | MRQ   | Rsvd | MRQ RSS |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		 *   | Checksum | Ident  |         | Queue |      |  Type   |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		 *   +------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		 *   +------------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		 *   63       48 47    32 31            20 19               0
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		printk(KERN_INFO "RWB[desc]      [ck ipid mrqhsh] "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
			"[vl   l0 ee  es] "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
		       "[ l3  l2  l1 hs] [reserved      ] ---------------- "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		       "[bi->skb] <-- Ext Rx Write-Back format\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		for (i = 0; i < rx_ring->count; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
			buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
			rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
			u1 = (struct my_u1 *)rx_desc_ps;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
			staterr =
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
				le32_to_cpu(rx_desc_ps->wb.middle.status_error);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
			if (staterr & E1000_RXD_STAT_DD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
				/* Descriptor Done */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
				printk(KERN_INFO "RWB[0x%03X]     %016llX "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
					"%016llX %016llX %016llX "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
					"---------------- %p", i,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
					(unsigned long long)le64_to_cpu(u1->a),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
					(unsigned long long)le64_to_cpu(u1->b),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
					(unsigned long long)le64_to_cpu(u1->c),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
					(unsigned long long)le64_to_cpu(u1->d),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
					buffer_info->skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
			} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
				printk(KERN_INFO "R  [0x%03X]     %016llX "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
					"%016llX %016llX %016llX %016llX %p", i,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
					(unsigned long long)le64_to_cpu(u1->a),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
					(unsigned long long)le64_to_cpu(u1->b),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
					(unsigned long long)le64_to_cpu(u1->c),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
					(unsigned long long)le64_to_cpu(u1->d),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
					(unsigned long long)buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
					buffer_info->skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
				if (netif_msg_pktdata(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
					print_hex_dump(KERN_INFO, "",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
						DUMP_PREFIX_ADDRESS, 16, 1,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
						phys_to_virt(buffer_info->dma),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
						adapter->rx_ps_bsize0, true);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			if (i == rx_ring->next_to_use)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
				printk(KERN_CONT " NTU\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
			else if (i == rx_ring->next_to_clean)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
				printk(KERN_CONT " NTC\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
			else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
				printk(KERN_CONT "\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	case 0:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		/* Legacy Receive Descriptor Format
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
		 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		 * +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		 * |                Buffer Address [63:0]                |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		 * +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		 * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
		 * +-----------------------------------------------------+
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
		 * 63       48 47    40 39      32 31         16 15      0
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
		printk(KERN_INFO "Rl[desc]     [address 63:0  ] "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
			"[vl er S cks ln] [bi->dma       ] [bi->skb] "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
			"<-- Legacy format\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
		for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
			rx_desc = E1000_RX_DESC(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
			buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
			u0 = (struct my_u0 *)rx_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
			printk(KERN_INFO "Rl[0x%03X]    %016llX %016llX "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
				"%016llX %p", i,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
				(unsigned long long)le64_to_cpu(u0->a),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
				(unsigned long long)le64_to_cpu(u0->b),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
				(unsigned long long)buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
				buffer_info->skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
			if (i == rx_ring->next_to_use)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
				printk(KERN_CONT " NTU\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
			else if (i == rx_ring->next_to_clean)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
				printk(KERN_CONT " NTC\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
			else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
				printk(KERN_CONT "\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
			if (netif_msg_pktdata(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
				print_hex_dump(KERN_INFO, "",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
					DUMP_PREFIX_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
					16, 1, phys_to_virt(buffer_info->dma),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
					adapter->rx_buffer_len, true);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
exit:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
 * e1000_desc_unused - calculate if we have unused descriptors
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
static int e1000_desc_unused(struct e1000_ring *ring)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	if (ring->next_to_clean > ring->next_to_use)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
		return ring->next_to_clean - ring->next_to_use - 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
 * e1000_receive_skb - helper function to handle Rx indications
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
 * @status: descriptor status field as written by hardware
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
 * @skb: pointer to sk_buff to be indicated to stack
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
static void e1000_receive_skb(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
			      struct net_device *netdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
			      struct sk_buff *skb,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
			      u8 status, __le16 vlan)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	skb->protocol = eth_type_trans(skb, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
				 le16_to_cpu(vlan), skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		napi_gro_receive(&adapter->napi, skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
 * e1000_rx_checksum - Receive Checksum Offload for 82543
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
 * @adapter:     board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
 * @status_err:  receive descriptor status and error fields
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
 * @csum:	receive descriptor csum field
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
 * @sk_buff:     socket buffer with received data
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
			      u32 csum, struct sk_buff *skb)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	u16 status = (u16)status_err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
	u8 errors = (u8)(status_err >> 24);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	skb_checksum_none_assert(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	/* Ignore Checksum bit is set */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	if (status & E1000_RXD_STAT_IXSM)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	/* TCP/UDP checksum error bit is set */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	if (errors & E1000_RXD_ERR_TCPE) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
		/* let the stack verify checksum errors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		adapter->hw_csum_err++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	/* TCP/UDP Checksum has not been calculated */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	/* It must be a TCP or UDP packet with a valid checksum */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	if (status & E1000_RXD_STAT_TCPCS) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		/* TCP checksum is good */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		skb->ip_summed = CHECKSUM_UNNECESSARY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		 * IP fragment with UDP payload
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		 * Hardware complements the payload checksum, so we undo it
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		 * and then put the value in host order for further stack use.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		__sum16 sum = (__force __sum16)htons(csum);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
		skb->csum = csum_unfold(~sum);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
		skb->ip_summed = CHECKSUM_COMPLETE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
	adapter->hw_csum_good++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
 * @adapter: address of board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
				   int cleaned_count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	struct e1000_rx_desc *rx_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
	struct sk_buff *skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
	unsigned int bufsz = adapter->rx_buffer_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
	i = rx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	while (cleaned_count--) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
		skb = buffer_info->skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
		if (skb) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
			skb_trim(skb, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
			goto map_skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
		if (!skb) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
			/* Better luck next round */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
			adapter->alloc_rx_buff_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
		buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
map_skb:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
						  adapter->rx_buffer_len,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
						  DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
			dev_err(&pdev->dev, "RX DMA map failed\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
			adapter->rx_dma_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
		rx_desc = E1000_RX_DESC(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
			 * Force memory writes to complete before letting h/w
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
			 * know there are new descriptors to fetch.  (Only
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
			 * applicable for weak-ordered memory model archs,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
			 * such as IA-64).
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
			wmb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
			writel(i, adapter->hw.hw_addr + rx_ring->tail);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
		if (i == rx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
			i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	rx_ring->next_to_use = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
 * @adapter: address of board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
				      int cleaned_count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	union e1000_rx_desc_packet_split *rx_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	struct e1000_ps_page *ps_page;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	struct sk_buff *skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	unsigned int i, j;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	i = rx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	while (cleaned_count--) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
			ps_page = &buffer_info->ps_pages[j];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
			if (j >= adapter->rx_ps_pages) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
				/* all unused desc entries get hw null ptr */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
				rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
				continue;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
			if (!ps_page->page) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
				ps_page->page = netdev_alloc_page(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
				if (!ps_page->page) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
					adapter->alloc_rx_buff_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
					goto no_buffers;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
				}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
				ps_page->dma = dma_map_page(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
							    ps_page->page,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
							    0, PAGE_SIZE,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
							    DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
				if (dma_mapping_error(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
						      ps_page->dma)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
					dev_err(&adapter->pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
					  "RX DMA page map failed\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
					adapter->rx_dma_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
					goto no_buffers;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
				}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
			 * Refresh the desc even if buffer_addrs
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
			 * didn't change because each write-back
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
			 * erases this info.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
			rx_desc->read.buffer_addr[j+1] =
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
			     cpu_to_le64(ps_page->dma);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		skb = netdev_alloc_skb_ip_align(netdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
						adapter->rx_ps_bsize0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
		if (!skb) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
			adapter->alloc_rx_buff_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
		buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
						  adapter->rx_ps_bsize0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
						  DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
			dev_err(&pdev->dev, "RX DMA map failed\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
			adapter->rx_dma_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
			/* cleanup skb */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
			dev_kfree_skb_any(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
			buffer_info->skb = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
			 * Force memory writes to complete before letting h/w
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
			 * know there are new descriptors to fetch.  (Only
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
			 * applicable for weak-ordered memory model archs,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
			 * such as IA-64).
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
			wmb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
			writel(i<<1, adapter->hw.hw_addr + rx_ring->tail);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
		i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		if (i == rx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
			i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
no_buffers:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	rx_ring->next_to_use = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
 * @adapter: address of board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
 * @cleaned_count: number of buffers to allocate this pass
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
                                         int cleaned_count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	struct e1000_rx_desc *rx_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	struct sk_buff *skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
	unsigned int bufsz = 256 - 16 /* for skb_reserve */;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	i = rx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	while (cleaned_count--) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		skb = buffer_info->skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		if (skb) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
			skb_trim(skb, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
			goto check_page;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
		if (unlikely(!skb)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
			/* Better luck next round */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
			adapter->alloc_rx_buff_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
		buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
check_page:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
		/* allocate a new page if necessary */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
		if (!buffer_info->page) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
			buffer_info->page = alloc_page(GFP_ATOMIC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
			if (unlikely(!buffer_info->page)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
				adapter->alloc_rx_buff_failed++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
				break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
		if (!buffer_info->dma)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
			buffer_info->dma = dma_map_page(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
			                                buffer_info->page, 0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
			                                PAGE_SIZE,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
							DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
		rx_desc = E1000_RX_DESC(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
		if (unlikely(++i == rx_ring->count))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
			i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
		buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	if (likely(rx_ring->next_to_use != i)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		rx_ring->next_to_use = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
		if (unlikely(i-- == 0))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
			i = (rx_ring->count - 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		/* Force memory writes to complete before letting h/w
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		 * know there are new descriptors to fetch.  (Only
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		 * applicable for weak-ordered memory model archs,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		 * such as IA-64). */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
		wmb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		writel(i, adapter->hw.hw_addr + rx_ring->tail);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
 * the return value indicates whether actual cleaning was done, there
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
 * is no guarantee that everything was cleaned
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
			       int *work_done, int work_to_do)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	struct e1000_rx_desc *rx_desc, *next_rxd;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	struct e1000_buffer *buffer_info, *next_buffer;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	u32 length;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	int cleaned_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
	bool cleaned = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
	i = rx_ring->next_to_clean;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	rx_desc = E1000_RX_DESC(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
	buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
	while (rx_desc->status & E1000_RXD_STAT_DD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		struct sk_buff *skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		u8 status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		if (*work_done >= work_to_do)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		(*work_done)++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
		rmb();	/* read descriptor and rx_buffer_info after status DD */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		status = rx_desc->status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		skb = buffer_info->skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		buffer_info->skb = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		prefetch(skb->data - NET_IP_ALIGN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
		if (i == rx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
			i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
		next_rxd = E1000_RX_DESC(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		prefetch(next_rxd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
		next_buffer = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
		cleaned = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		cleaned_count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		dma_unmap_single(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
				 buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
				 adapter->rx_buffer_len,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
				 DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
		buffer_info->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		length = le16_to_cpu(rx_desc->length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
		 * !EOP means multiple descriptors were used to store a single
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
		 * packet, if that's the case we need to toss it.  In fact, we
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		 * need to toss every packet with the EOP bit clear and the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		 * next frame that _does_ have the EOP bit set, as it is by
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		 * definition only a frame fragment
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
			adapter->flags2 |= FLAG2_IS_DISCARDING;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
			/* All receives must fit into a single buffer */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
			e_dbg("Receive packet consumed multiple buffers\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
			/* recycle */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
			buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
			if (status & E1000_RXD_STAT_EOP)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
			goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		if (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
			/* recycle */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
			buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
			goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		/* adjust length to remove Ethernet CRC */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
			length -= 4;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		total_rx_bytes += length;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		total_rx_packets++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
		 * code added for copybreak, this should improve
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
		 * performance for small packets with large amounts
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		 * of reassembly being done in the stack
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
		if (length < copybreak) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
			struct sk_buff *new_skb =
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
			    netdev_alloc_skb_ip_align(netdev, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
			if (new_skb) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
				skb_copy_to_linear_data_offset(new_skb,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
							       -NET_IP_ALIGN,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
							       (skb->data -
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
								NET_IP_ALIGN),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
							       (length +
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
								NET_IP_ALIGN));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
				/* save the skb in buffer_info as good */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
				buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
				skb = new_skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
			/* else just continue with the old one */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
		/* end copybreak code */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
		skb_put(skb, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
		/* Receive Checksum Offload */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
		e1000_rx_checksum(adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
				  (u32)(status) |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
				  ((u32)(rx_desc->errors) << 24),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
				  le16_to_cpu(rx_desc->csum), skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
next_desc:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		rx_desc->status = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
		/* return some buffers to hardware, one at a time is too slow */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
			adapter->alloc_rx_buf(adapter, cleaned_count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
			cleaned_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
		/* use prefetched values */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		rx_desc = next_rxd;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		buffer_info = next_buffer;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	rx_ring->next_to_clean = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	cleaned_count = e1000_desc_unused(rx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	if (cleaned_count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		adapter->alloc_rx_buf(adapter, cleaned_count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	adapter->total_rx_bytes += total_rx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	adapter->total_rx_packets += total_rx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	netdev->stats.rx_bytes += total_rx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	netdev->stats.rx_packets += total_rx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	return cleaned;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
static void e1000_put_txbuf(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
			     struct e1000_buffer *buffer_info)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	if (buffer_info->dma) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		if (buffer_info->mapped_as_page)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
				       buffer_info->length, DMA_TO_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
		else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
					 buffer_info->length, DMA_TO_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
		buffer_info->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	if (buffer_info->skb) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
		dev_kfree_skb_any(buffer_info->skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
		buffer_info->skb = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	buffer_info->time_stamp = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
static void e1000_print_hw_hang(struct work_struct *work)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	struct e1000_adapter *adapter = container_of(work,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	                                             struct e1000_adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	                                             print_hang_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	unsigned int i = tx_ring->next_to_clean;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	u16 phy_status, phy_1000t_status, phy_ext_status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	u16 pci_status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	e1e_rphy(hw, PHY_STATUS, &phy_status);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	/* detected Hardware unit hang */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	e_err("Detected Hardware Unit Hang:\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	      "  TDH                  <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	      "  TDT                  <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	      "  next_to_use          <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	      "  next_to_clean        <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
	      "buffer_info[next_to_clean]:\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	      "  time_stamp           <%lx>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	      "  next_to_watch        <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	      "  jiffies              <%lx>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	      "  next_to_watch.status <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	      "MAC Status             <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	      "PHY Status             <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	      "PHY 1000BASE-T Status  <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	      "PHY Extended Status    <%x>\n"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	      "PCI Status             <%x>\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	      readl(adapter->hw.hw_addr + tx_ring->head),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	      readl(adapter->hw.hw_addr + tx_ring->tail),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	      tx_ring->next_to_use,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	      tx_ring->next_to_clean,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	      tx_ring->buffer_info[eop].time_stamp,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	      eop,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	      jiffies,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	      eop_desc->upper.fields.status,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	      er32(STATUS),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	      phy_status,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	      phy_1000t_status,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	      phy_ext_status,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	      pci_status);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
 * the return value indicates whether actual cleaning was done, there
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
 * is no guarantee that everything was cleaned
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	struct e1000_tx_desc *tx_desc, *eop_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	unsigned int i, eop;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	unsigned int count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	i = tx_ring->next_to_clean;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	eop = tx_ring->buffer_info[i].next_to_watch;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	       (count < tx_ring->count)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		bool cleaned = false;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		rmb(); /* read buffer_info after eop_desc */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		for (; !cleaned; count++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
			tx_desc = E1000_TX_DESC(*tx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
			buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
			cleaned = (i == eop);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
			if (cleaned) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
				total_tx_packets += buffer_info->segs;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
				total_tx_bytes += buffer_info->bytecount;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
			e1000_put_txbuf(adapter, buffer_info);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
			tx_desc->upper.data = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
			i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
			if (i == tx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
				i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
		if (i == tx_ring->next_to_use)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		eop = tx_ring->buffer_info[i].next_to_watch;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
	tx_ring->next_to_clean = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
#define TX_WAKE_THRESHOLD 32
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	if (count && netif_carrier_ok(netdev) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
		/* Make sure that anybody stopping the queue after this
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		 * sees the new next_to_clean.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		smp_mb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		if (netif_queue_stopped(netdev) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
			netif_wake_queue(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
			++adapter->restart_queue;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
	if (adapter->detect_tx_hung) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
		 * Detect a transmit hang in hardware, this serializes the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
		 * check with the clearing of time_stamp and movement of i
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		adapter->detect_tx_hung = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		if (tx_ring->buffer_info[i].time_stamp &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
			       + (adapter->tx_timeout_factor * HZ)) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
			schedule_work(&adapter->print_hang_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
			netif_stop_queue(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
	adapter->total_tx_bytes += total_tx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
	adapter->total_tx_packets += total_tx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
	netdev->stats.tx_bytes += total_tx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	netdev->stats.tx_packets += total_tx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	return count < tx_ring->count;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
 * the return value indicates whether actual cleaning was done, there
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
 * is no guarantee that everything was cleaned
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
				  int *work_done, int work_to_do)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	struct e1000_buffer *buffer_info, *next_buffer;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	struct e1000_ps_page *ps_page;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	struct sk_buff *skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	unsigned int i, j;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	u32 length, staterr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	int cleaned_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	bool cleaned = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	i = rx_ring->next_to_clean;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
	buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	while (staterr & E1000_RXD_STAT_DD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		if (*work_done >= work_to_do)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		(*work_done)++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		skb = buffer_info->skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		rmb();	/* read descriptor and rx_buffer_info after status DD */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		/* in the packet split case this is header only */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		prefetch(skb->data - NET_IP_ALIGN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		if (i == rx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
			i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		prefetch(next_rxd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		next_buffer = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		cleaned = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
		cleaned_count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		dma_unmap_single(&pdev->dev, buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
				 adapter->rx_ps_bsize0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
				 DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		buffer_info->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		/* see !EOP comment in other rx routine */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		if (!(staterr & E1000_RXD_STAT_EOP))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
			adapter->flags2 |= FLAG2_IS_DISCARDING;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			e_dbg("Packet Split buffers didn't pick up the full "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
			      "packet\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			dev_kfree_skb_irq(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
			if (staterr & E1000_RXD_STAT_EOP)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
		if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
			dev_kfree_skb_irq(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
			goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
		length = le16_to_cpu(rx_desc->wb.middle.length0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		if (!length) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
			e_dbg("Last part of the packet spanning multiple "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
			      "descriptors\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
			dev_kfree_skb_irq(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
			goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		/* Good Receive */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
		skb_put(skb, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		 * this looks ugly, but it seems compiler issues make it
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		 * more efficient than reusing j
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		 * page alloc/put takes too long and effects small packet
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		 * throughput, so unsplit small packets and save the alloc/put
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		 * only valid in softirq (napi) context to call kmap_*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
		if (l1 && (l1 <= copybreak) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		    ((length + l1) <= adapter->rx_ps_bsize0)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
			u8 *vaddr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
			ps_page = &buffer_info->ps_pages[0];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
			 * there is no documentation about how to call
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
			 * kmap_atomic, so we can't hold the mapping
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
			 * very long
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
			dma_sync_single_for_cpu(&pdev->dev, ps_page->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
						PAGE_SIZE, DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
			vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
			memcpy(skb_tail_pointer(skb), vaddr, l1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			dma_sync_single_for_device(&pdev->dev, ps_page->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
						   PAGE_SIZE, DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
			/* remove the CRC */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
			if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
				l1 -= 4;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
			skb_put(skb, l1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
			goto copydone;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		} /* if */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
			if (!length)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
				break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
			ps_page = &buffer_info->ps_pages[j];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
				       DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
			ps_page->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
			skb_add_rx_frag(skb, j, ps_page->page, 0, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
			ps_page->page = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		/* strip the ethernet crc, problem is we're using pages now so
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		 * this whole operation can get a little cpu intensive
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
			pskb_trim(skb, skb->len - 4);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
copydone:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		total_rx_bytes += skb->len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
		total_rx_packets++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		e1000_rx_checksum(adapter, staterr, le16_to_cpu(
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
			rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		if (rx_desc->wb.upper.header_status &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
			adapter->rx_hdr_split++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		e1000_receive_skb(adapter, netdev, skb,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
				  staterr, rx_desc->wb.middle.vlan);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
next_desc:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		buffer_info->skb = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		/* return some buffers to hardware, one at a time is too slow */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
			adapter->alloc_rx_buf(adapter, cleaned_count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			cleaned_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		/* use prefetched values */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		rx_desc = next_rxd;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		buffer_info = next_buffer;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	rx_ring->next_to_clean = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
	cleaned_count = e1000_desc_unused(rx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	if (cleaned_count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		adapter->alloc_rx_buf(adapter, cleaned_count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	adapter->total_rx_bytes += total_rx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	adapter->total_rx_packets += total_rx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	netdev->stats.rx_bytes += total_rx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
	netdev->stats.rx_packets += total_rx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
	return cleaned;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
 * e1000_consume_page - helper function
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
                               u16 length)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	bi->page = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	skb->len += length;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	skb->data_len += length;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	skb->truesize += length;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
 * the return value indicates whether actual cleaning was done, there
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
 * is no guarantee that everything was cleaned
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
                                     int *work_done, int work_to_do)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	struct e1000_rx_desc *rx_desc, *next_rxd;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
	struct e1000_buffer *buffer_info, *next_buffer;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
	u32 length;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
	int cleaned_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	bool cleaned = false;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	unsigned int total_rx_bytes=0, total_rx_packets=0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	i = rx_ring->next_to_clean;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
	rx_desc = E1000_RX_DESC(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
	buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	while (rx_desc->status & E1000_RXD_STAT_DD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		struct sk_buff *skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		u8 status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		if (*work_done >= work_to_do)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
		(*work_done)++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		rmb();	/* read descriptor and rx_buffer_info after status DD */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		status = rx_desc->status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		skb = buffer_info->skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		buffer_info->skb = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		++i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
		if (i == rx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
			i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		next_rxd = E1000_RX_DESC(*rx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		prefetch(next_rxd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		next_buffer = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
		cleaned = true;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		cleaned_count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
		dma_unmap_page(&pdev->dev, buffer_info->dma, PAGE_SIZE,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
			       DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		buffer_info->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
		length = le16_to_cpu(rx_desc->length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
		/* errors is only valid for DD + EOP descriptors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		if (unlikely((status & E1000_RXD_STAT_EOP) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
				/* recycle both page and skb */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
				buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
				/* an error means any chain goes out the window
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
				 * too */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
				if (rx_ring->rx_skb_top)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
					dev_kfree_skb(rx_ring->rx_skb_top);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
				rx_ring->rx_skb_top = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
				goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
#define rxtop rx_ring->rx_skb_top
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		if (!(status & E1000_RXD_STAT_EOP)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
			/* this descriptor is only the beginning (or middle) */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
			if (!rxtop) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
				/* this is the beginning of a chain */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
				rxtop = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
				                   0, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
			} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
				/* this is the middle of a chain */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
				skb_fill_page_desc(rxtop,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
				    skb_shinfo(rxtop)->nr_frags,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
				    buffer_info->page, 0, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
				/* re-use the skb, only consumed the page */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
				buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
			e1000_consume_page(buffer_info, rxtop, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
			goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
			if (rxtop) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
				/* end of the chain */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
				skb_fill_page_desc(rxtop,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
				    skb_shinfo(rxtop)->nr_frags,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
				    buffer_info->page, 0, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
				/* re-use the current skb, we only consumed the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
				 * page */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
				buffer_info->skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
				skb = rxtop;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
				rxtop = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
				e1000_consume_page(buffer_info, skb, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
			} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
				/* no chain, got EOP, this buf is the packet
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
				 * copybreak to save the put_page/alloc_page */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
				if (length <= copybreak &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
				    skb_tailroom(skb) >= length) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
					u8 *vaddr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
					vaddr = kmap_atomic(buffer_info->page,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
					                   KM_SKB_DATA_SOFTIRQ);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
					memcpy(skb_tail_pointer(skb), vaddr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
					       length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
					kunmap_atomic(vaddr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
					              KM_SKB_DATA_SOFTIRQ);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
					/* re-use the page, so don't erase
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
					 * buffer_info->page */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
					skb_put(skb, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
				} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
					skb_fill_page_desc(skb, 0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
					                   buffer_info->page, 0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
				                           length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
					e1000_consume_page(buffer_info, skb,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
					                   length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
				}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		e1000_rx_checksum(adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		                  (u32)(status) |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
		                  ((u32)(rx_desc->errors) << 24),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
		                  le16_to_cpu(rx_desc->csum), skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
		/* probably a little skewed due to removing CRC */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
		total_rx_bytes += skb->len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		total_rx_packets++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		/* eth type trans needs skb->data to point to something */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		if (!pskb_may_pull(skb, ETH_HLEN)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
			e_err("pskb_may_pull failed.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
			dev_kfree_skb(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
			goto next_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		e1000_receive_skb(adapter, netdev, skb, status,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
		                  rx_desc->special);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
next_desc:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
		rx_desc->status = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		/* return some buffers to hardware, one at a time is too slow */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
			adapter->alloc_rx_buf(adapter, cleaned_count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
			cleaned_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		/* use prefetched values */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		rx_desc = next_rxd;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		buffer_info = next_buffer;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	rx_ring->next_to_clean = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	cleaned_count = e1000_desc_unused(rx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
	if (cleaned_count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
		adapter->alloc_rx_buf(adapter, cleaned_count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	adapter->total_rx_bytes += total_rx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	adapter->total_rx_packets += total_rx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	netdev->stats.rx_bytes += total_rx_bytes;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
	netdev->stats.rx_packets += total_rx_packets;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	return cleaned;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	struct e1000_ps_page *ps_page;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	unsigned int i, j;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
	/* Free all the Rx ring sk_buffs */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	for (i = 0; i < rx_ring->count; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
		buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
		if (buffer_info->dma) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
			if (adapter->clean_rx == e1000_clean_rx_irq)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
				dma_unmap_single(&pdev->dev, buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
						 adapter->rx_buffer_len,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
						 DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
				dma_unmap_page(&pdev->dev, buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
				               PAGE_SIZE,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
					       DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
				dma_unmap_single(&pdev->dev, buffer_info->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
						 adapter->rx_ps_bsize0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
						 DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
			buffer_info->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
		if (buffer_info->page) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
			put_page(buffer_info->page);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
			buffer_info->page = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		if (buffer_info->skb) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
			dev_kfree_skb(buffer_info->skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
			buffer_info->skb = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
			ps_page = &buffer_info->ps_pages[j];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
			if (!ps_page->page)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
				break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
				       DMA_FROM_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
			ps_page->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
			put_page(ps_page->page);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
			ps_page->page = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	/* there also may be some cached data from a chained receive */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	if (rx_ring->rx_skb_top) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
		dev_kfree_skb(rx_ring->rx_skb_top);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
		rx_ring->rx_skb_top = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	/* Zero out the descriptor ring */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	memset(rx_ring->desc, 0, rx_ring->size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	rx_ring->next_to_clean = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	rx_ring->next_to_use = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	writel(0, adapter->hw.hw_addr + rx_ring->head);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	writel(0, adapter->hw.hw_addr + rx_ring->tail);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
static void e1000e_downshift_workaround(struct work_struct *work)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	struct e1000_adapter *adapter = container_of(work,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
					struct e1000_adapter, downshift_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
 * e1000_intr_msi - Interrupt Handler
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
 * @irq: interrupt number
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
 * @data: pointer to a network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
static irqreturn_t e1000_intr_msi(int irq, void *data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	struct net_device *netdev = data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	u32 icr = er32(ICR);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	 * read ICR disables interrupts using IAM
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	if (icr & E1000_ICR_LSC) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		hw->mac.get_link_status = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		 * ICH8 workaround-- Call gig speed drop workaround on cable
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
		 * disconnect (LSC) before accessing any PHY registers
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
		    (!(er32(STATUS) & E1000_STATUS_LU)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
			schedule_work(&adapter->downshift_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		 * 80003ES2LAN workaround-- For packet buffer work-around on
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
		 * link down event; disable receives here in the ISR and reset
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
		 * adapter in watchdog
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		if (netif_carrier_ok(netdev) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
			/* disable receives */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
			u32 rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
			adapter->flags |= FLAG_RX_RESTART_NOW;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
		/* guard against interrupt when we're going down */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
		if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	if (napi_schedule_prep(&adapter->napi)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		adapter->total_tx_bytes = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		adapter->total_tx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		adapter->total_rx_bytes = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		adapter->total_rx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		__napi_schedule(&adapter->napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	return IRQ_HANDLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
 * e1000_intr - Interrupt Handler
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
 * @irq: interrupt number
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
 * @data: pointer to a network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
static irqreturn_t e1000_intr(int irq, void *data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	struct net_device *netdev = data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
	u32 rctl, icr = er32(ICR);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		return IRQ_NONE;  /* Not our interrupt */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	 * IMS will not auto-mask if INT_ASSERTED is not set, and if it is
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	 * not set, then the adapter didn't send an interrupt
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	if (!(icr & E1000_ICR_INT_ASSERTED))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
		return IRQ_NONE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	 * Interrupt Auto-Mask...upon reading ICR,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	 * interrupts are masked.  No need for the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	 * IMC write
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
	if (icr & E1000_ICR_LSC) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
		hw->mac.get_link_status = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
		 * ICH8 workaround-- Call gig speed drop workaround on cable
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
		 * disconnect (LSC) before accessing any PHY registers
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
		    (!(er32(STATUS) & E1000_STATUS_LU)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
			schedule_work(&adapter->downshift_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
		 * 80003ES2LAN workaround--
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		 * For packet buffer work-around on link down event;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		 * disable receives here in the ISR and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		 * reset adapter in watchdog
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		if (netif_carrier_ok(netdev) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
			/* disable receives */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
			rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
			adapter->flags |= FLAG_RX_RESTART_NOW;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		/* guard against interrupt when we're going down */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	if (napi_schedule_prep(&adapter->napi)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		adapter->total_tx_bytes = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
		adapter->total_tx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		adapter->total_rx_bytes = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		adapter->total_rx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		__napi_schedule(&adapter->napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	return IRQ_HANDLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
static irqreturn_t e1000_msix_other(int irq, void *data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	struct net_device *netdev = data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	u32 icr = er32(ICR);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
			ew32(IMS, E1000_IMS_OTHER);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		return IRQ_NONE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
	if (icr & adapter->eiac_mask)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		ew32(ICS, (icr & adapter->eiac_mask));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	if (icr & E1000_ICR_OTHER) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
		if (!(icr & E1000_ICR_LSC))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
			goto no_link_interrupt;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		hw->mac.get_link_status = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		/* guard against interrupt when we're going down */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
no_link_interrupt:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	return IRQ_HANDLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
static irqreturn_t e1000_intr_msix_tx(int irq, void *data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	struct net_device *netdev = data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	adapter->total_tx_bytes = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	adapter->total_tx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
	if (!e1000_clean_tx_irq(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		/* Ring was not completely cleaned, so fire another interrupt */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		ew32(ICS, tx_ring->ims_val);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
	return IRQ_HANDLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	struct net_device *netdev = data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	/* Write the ITR value calculated at the end of the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	 * previous interrupt.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	if (adapter->rx_ring->set_itr) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		writel(1000000000 / (adapter->rx_ring->itr_val * 256),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		       adapter->hw.hw_addr + adapter->rx_ring->itr_register);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
		adapter->rx_ring->set_itr = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	if (napi_schedule_prep(&adapter->napi)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		adapter->total_rx_bytes = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		adapter->total_rx_packets = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		__napi_schedule(&adapter->napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	return IRQ_HANDLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
 * e1000_configure_msix - Configure MSI-X hardware
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
 * e1000_configure_msix sets up the hardware to properly
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
 * generate MSI-X interrupts.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
static void e1000_configure_msix(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
	int vector = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	u32 ctrl_ext, ivar = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	adapter->eiac_mask = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	if (hw->mac.type == e1000_82574) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
		u32 rfctl = er32(RFCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
		rfctl |= E1000_RFCTL_ACK_DIS;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
		ew32(RFCTL, rfctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
#define E1000_IVAR_INT_ALLOC_VALID	0x8
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	/* Configure Rx vector */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	rx_ring->ims_val = E1000_IMS_RXQ0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	adapter->eiac_mask |= rx_ring->ims_val;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	if (rx_ring->itr_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		writel(1000000000 / (rx_ring->itr_val * 256),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
		       hw->hw_addr + rx_ring->itr_register);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		writel(1, hw->hw_addr + rx_ring->itr_register);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	/* Configure Tx vector */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	tx_ring->ims_val = E1000_IMS_TXQ0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	vector++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	if (tx_ring->itr_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
		writel(1000000000 / (tx_ring->itr_val * 256),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
		       hw->hw_addr + tx_ring->itr_register);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
		writel(1, hw->hw_addr + tx_ring->itr_register);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
	adapter->eiac_mask |= tx_ring->ims_val;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	/* set vector for Other Causes, e.g. link changes */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	vector++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	if (rx_ring->itr_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
		writel(1000000000 / (rx_ring->itr_val * 256),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		       hw->hw_addr + E1000_EITR_82574(vector));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	/* Cause Tx interrupts on every write back */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	ivar |= (1 << 31);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	ew32(IVAR, ivar);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	/* enable MSI-X PBA support */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	ctrl_ext = er32(CTRL_EXT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	/* Auto-Mask Other interrupts upon ICR read */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
#define E1000_EIAC_MASK_82574   0x01F00000
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	ew32(CTRL_EXT, ctrl_ext);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	e1e_flush();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	if (adapter->msix_entries) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		pci_disable_msix(adapter->pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
		kfree(adapter->msix_entries);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		adapter->msix_entries = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		pci_disable_msi(adapter->pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		adapter->flags &= ~FLAG_MSI_ENABLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
 * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
 * Attempt to configure interrupts using the best available
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
 * capabilities of the hardware and kernel.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
	int err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
	int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	switch (adapter->int_mode) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	case E1000E_INT_MODE_MSIX:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		if (adapter->flags & FLAG_HAS_MSIX) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
			adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			adapter->msix_entries = kcalloc(adapter->num_vectors,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
						      sizeof(struct msix_entry),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
						      GFP_KERNEL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
			if (adapter->msix_entries) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
				for (i = 0; i < adapter->num_vectors; i++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
					adapter->msix_entries[i].entry = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
				err = pci_enable_msix(adapter->pdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
						      adapter->msix_entries,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
						      adapter->num_vectors);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
				if (err == 0) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
					return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
				}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
			/* MSI-X failed, so fall through and try MSI */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
			e_err("Failed to initialize MSI-X interrupts.  "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
			      "Falling back to MSI interrupts.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
			e1000e_reset_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		adapter->int_mode = E1000E_INT_MODE_MSI;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		/* Fall through */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	case E1000E_INT_MODE_MSI:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
		if (!pci_enable_msi(adapter->pdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
			adapter->flags |= FLAG_MSI_ENABLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
			e_err("Failed to initialize MSI interrupts.  Falling "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
			      "back to legacy interrupts.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		/* Fall through */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
	case E1000E_INT_MODE_LEGACY:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
		/* Don't do anything; this is the system default */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	/* store the number of vectors being used */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	adapter->num_vectors = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
 * e1000_request_msix - Initialize MSI-X interrupts
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
 * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
 * kernel.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
static int e1000_request_msix(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	int err = 0, vector = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
		sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	err = request_irq(adapter->msix_entries[vector].vector,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
			  e1000_intr_msix_rx, entropy ? IRQF_SAMPLE_RANDOM : 0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			  adapter->rx_ring->name, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		goto out;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	adapter->rx_ring->itr_register = E1000_EITR_82574(vector);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	adapter->rx_ring->itr_val = adapter->itr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	vector++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
		sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	err = request_irq(adapter->msix_entries[vector].vector,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
			  netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		goto out;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	adapter->tx_ring->itr_register = E1000_EITR_82574(vector);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	adapter->tx_ring->itr_val = adapter->itr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
	vector++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	err = request_irq(adapter->msix_entries[vector].vector,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
			  e1000_msix_other, 0, netdev->name, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
		goto out;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	e1000_configure_msix(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
out:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
 * e1000_request_irq - initialize interrupts
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
 * Attempts to configure interrupts using the best available
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
 * capabilities of the hardware and kernel.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
static int e1000_request_irq(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	int err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	int irq_flags = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	if (adapter->msix_entries) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
		err = e1000_request_msix(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
		if (!err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
			return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		/* fall back to MSI */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
		e1000e_reset_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
		adapter->int_mode = E1000E_INT_MODE_MSI;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
		e1000e_set_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	if (adapter->flags & FLAG_MSI_ENABLED) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
		err = request_irq(adapter->pdev->irq, e1000_intr_msi,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
				  entropy ? IRQF_SAMPLE_RANDOM : 0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
				  netdev->name, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
		if (!err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
			return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		/* fall back to legacy interrupt */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
		e1000e_reset_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	if (entropy)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
		irq_flags |= IRQF_SAMPLE_RANDOM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
	err = request_irq(adapter->pdev->irq, e1000_intr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
			  irq_flags | IRQF_SHARED, netdev->name, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
		e_err("Unable to allocate interrupt, Error: %d\n", err);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
static void e1000_free_irq(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	if (adapter->msix_entries) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
		int vector = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
		free_irq(adapter->msix_entries[vector].vector, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
		vector++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
		free_irq(adapter->msix_entries[vector].vector, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		vector++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
		/* Other Causes interrupt vector */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
		free_irq(adapter->msix_entries[vector].vector, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
	free_irq(adapter->pdev->irq, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
 * e1000_irq_disable - Mask off interrupt generation on the NIC
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
static void e1000_irq_disable(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
	ew32(IMC, ~0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	if (adapter->msix_entries)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		ew32(EIAC_82574, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	e1e_flush();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	if (adapter->msix_entries) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
		int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
		for (i = 0; i < adapter->num_vectors; i++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
			synchronize_irq(adapter->msix_entries[i].vector);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
		synchronize_irq(adapter->pdev->irq);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
 * e1000_irq_enable - Enable default interrupt generation settings
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
static void e1000_irq_enable(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
	if (adapter->msix_entries) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
		ew32(IMS, IMS_ENABLE_MASK);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	e1e_flush();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
 * e1000_get_hw_control - get control of the h/w from f/w
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
 * @adapter: address of board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
 * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
 * For ASF and Pass Through versions of f/w this means that
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
 * the driver is loaded. For AMT version (only with 82573)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
 * of the f/w this means that the network i/f is open.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
static void e1000_get_hw_control(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	u32 ctrl_ext;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	u32 swsm;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	/* Let firmware know the driver has taken over */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
		swsm = er32(SWSM);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
		ctrl_ext = er32(CTRL_EXT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
 * e1000_release_hw_control - release control of the h/w to f/w
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
 * @adapter: address of board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
 * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
 * For ASF and Pass Through versions of f/w this means that the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
 * driver is no longer loaded. For AMT version (only with 82573) i
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
 * of the f/w this means that the network i/f is closed.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
static void e1000_release_hw_control(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	u32 ctrl_ext;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
	u32 swsm;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
	/* Let firmware taken over control of h/w */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
		swsm = er32(SWSM);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
		ctrl_ext = er32(CTRL_EXT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
 * @e1000_alloc_ring - allocate memory for a ring structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
				struct e1000_ring *ring)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
					GFP_KERNEL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
	if (!ring->desc)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
		return -ENOMEM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
 * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
 * Return 0 on success, negative on failure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	int err = -ENOMEM, size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	size = sizeof(struct e1000_buffer) * tx_ring->count;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	tx_ring->buffer_info = vmalloc(size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
	if (!tx_ring->buffer_info)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		goto err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	memset(tx_ring->buffer_info, 0, size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
	/* round up to nearest 4K */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
	tx_ring->size = ALIGN(tx_ring->size, 4096);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	err = e1000_alloc_ring_dma(adapter, tx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
		goto err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	tx_ring->next_to_use = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
	tx_ring->next_to_clean = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
err:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	vfree(tx_ring->buffer_info);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
 * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
 * Returns 0 on success, negative on failure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	int i, size, desc_len, err = -ENOMEM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
	size = sizeof(struct e1000_buffer) * rx_ring->count;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	rx_ring->buffer_info = vmalloc(size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	if (!rx_ring->buffer_info)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
		goto err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	memset(rx_ring->buffer_info, 0, size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
	for (i = 0; i < rx_ring->count; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
						sizeof(struct e1000_ps_page),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
						GFP_KERNEL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
		if (!buffer_info->ps_pages)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
			goto err_pages;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	desc_len = sizeof(union e1000_rx_desc_packet_split);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	/* Round up to nearest 4K */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	rx_ring->size = rx_ring->count * desc_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	rx_ring->size = ALIGN(rx_ring->size, 4096);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	err = e1000_alloc_ring_dma(adapter, rx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		goto err_pages;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	rx_ring->next_to_clean = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
	rx_ring->next_to_use = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	rx_ring->rx_skb_top = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
err_pages:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	for (i = 0; i < rx_ring->count; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
		buffer_info = &rx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
		kfree(buffer_info->ps_pages);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
err:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	vfree(rx_ring->buffer_info);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
 * e1000_clean_tx_ring - Free Tx Buffers
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	unsigned long size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	for (i = 0; i < tx_ring->count; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
		buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
		e1000_put_txbuf(adapter, buffer_info);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	size = sizeof(struct e1000_buffer) * tx_ring->count;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	memset(tx_ring->buffer_info, 0, size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	memset(tx_ring->desc, 0, tx_ring->size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	tx_ring->next_to_use = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	tx_ring->next_to_clean = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	writel(0, adapter->hw.hw_addr + tx_ring->head);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	writel(0, adapter->hw.hw_addr + tx_ring->tail);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
 * e1000e_free_tx_resources - Free Tx Resources per Queue
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
 * Free all transmit software resources
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
void e1000e_free_tx_resources(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	e1000_clean_tx_ring(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	vfree(tx_ring->buffer_info);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	tx_ring->buffer_info = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
			  tx_ring->dma);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	tx_ring->desc = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
 * e1000e_free_rx_resources - Free Rx Resources
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
 * Free all receive software resources
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
void e1000e_free_rx_resources(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
	int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	e1000_clean_rx_ring(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	for (i = 0; i < rx_ring->count; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
		kfree(rx_ring->buffer_info[i].ps_pages);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	vfree(rx_ring->buffer_info);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	rx_ring->buffer_info = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
			  rx_ring->dma);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	rx_ring->desc = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
 * e1000_update_itr - update the dynamic ITR value based on statistics
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
 * @adapter: pointer to adapter
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
 * @itr_setting: current adapter->itr
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
 * @packets: the number of packets during this measurement interval
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
 * @bytes: the number of bytes during this measurement interval
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
 *      Stores a new ITR value based on packets and byte
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
 *      counts during the last interrupt.  The advantage of per interrupt
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
 *      computation is faster updates and more accurate ITR for the current
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
 *      traffic pattern.  Constants in this function were computed
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
 *      based on theoretical maximum wire speed and thresholds were set based
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
 *      on testing data as well as attempting to minimize response time
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
 *      while increasing bulk throughput.  This functionality is controlled
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
 *      by the InterruptThrottleRate module parameter.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
				     u16 itr_setting, int packets,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
				     int bytes)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	unsigned int retval = itr_setting;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
	if (packets == 0)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
		goto update_itr_done;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	switch (itr_setting) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	case lowest_latency:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		/* handle TSO and jumbo frames */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
		if (bytes/packets > 8000)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
			retval = bulk_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
		else if ((packets < 5) && (bytes > 512)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
			retval = low_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	case low_latency:  /* 50 usec aka 20000 ints/s */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
		if (bytes > 10000) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
			/* this if handles the TSO accounting */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
			if (bytes/packets > 8000) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
				retval = bulk_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
			} else if ((packets < 10) || ((bytes/packets) > 1200)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
				retval = bulk_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
			} else if ((packets > 35)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
				retval = lowest_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
		} else if (bytes/packets > 2000) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
			retval = bulk_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
		} else if (packets <= 2 && bytes < 512) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
			retval = lowest_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	case bulk_latency: /* 250 usec aka 4000 ints/s */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		if (bytes > 25000) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
			if (packets > 35) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
				retval = low_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
		} else if (bytes < 6000) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			retval = low_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
update_itr_done:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	return retval;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
static void e1000_set_itr(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
	u16 current_itr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	u32 new_itr = adapter->itr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	if (adapter->link_speed != SPEED_1000) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
		current_itr = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
		new_itr = 4000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
		goto set_itr_now;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	if (adapter->flags2 & FLAG2_DISABLE_AIM) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
		new_itr = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
		goto set_itr_now;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	adapter->tx_itr = e1000_update_itr(adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
				    adapter->tx_itr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
				    adapter->total_tx_packets,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
				    adapter->total_tx_bytes);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
		adapter->tx_itr = low_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	adapter->rx_itr = e1000_update_itr(adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
				    adapter->rx_itr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
				    adapter->total_rx_packets,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
				    adapter->total_rx_bytes);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
		adapter->rx_itr = low_latency;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
	switch (current_itr) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	/* counts and packets in update_itr are dependent on these numbers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	case lowest_latency:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		new_itr = 70000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	case low_latency:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		new_itr = 20000; /* aka hwitr = ~200 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	case bulk_latency:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		new_itr = 4000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
set_itr_now:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
	if (new_itr != adapter->itr) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
		 * this attempts to bias the interrupt rate towards Bulk
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		 * by adding intermediate steps when interrupt rate is
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		 * increasing
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
		new_itr = new_itr > adapter->itr ?
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
			     min(adapter->itr + (new_itr >> 2), new_itr) :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
			     new_itr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
		adapter->itr = new_itr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		adapter->rx_ring->itr_val = new_itr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		if (adapter->msix_entries)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
			adapter->rx_ring->set_itr = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
			if (new_itr)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
				ew32(ITR, 1000000000 / (new_itr * 256));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
			else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
				ew32(ITR, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
 * e1000_alloc_queues - Allocate memory for all rings
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
 * @adapter: board private structure to initialize
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
	if (!adapter->tx_ring)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
		goto err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
	adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	if (!adapter->rx_ring)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
		goto err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
err:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	e_err("Unable to allocate memory for queues\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	kfree(adapter->rx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	kfree(adapter->tx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	return -ENOMEM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
 * e1000_clean - NAPI Rx polling callback
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
 * @napi: struct associated with this polling callback
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
 * @budget: amount of packets driver is allowed to process this poll
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
static int e1000_clean(struct napi_struct *napi, int budget)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
	struct net_device *poll_dev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	int tx_cleaned = 1, work_done = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	adapter = netdev_priv(poll_dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	if (adapter->msix_entries &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
	    !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
		goto clean_rx;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	tx_cleaned = e1000_clean_tx_irq(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
clean_rx:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	adapter->clean_rx(adapter, &work_done, budget);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	if (!tx_cleaned)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
		work_done = budget;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	/* If budget not fully consumed, exit the polling mode */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
	if (work_done < budget) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		if (adapter->itr_setting & 3)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
			e1000_set_itr(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
		napi_complete(napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
			if (adapter->msix_entries)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
				ew32(IMS, adapter->rx_ring->ims_val);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
			else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
				e1000_irq_enable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	return work_done;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	u32 vfta, index;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
	/* don't update vlan cookie if already programmed */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	if ((adapter->hw.mng_cookie.status &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
	    (vid == adapter->mng_vlan_id))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	/* add VID to filter table */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
		index = (vid >> 5) & 0x7F;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
		vfta |= (1 << (vid & 0x1F));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
		hw->mac.ops.write_vfta(hw, index, vfta);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	u32 vfta, index;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
	if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
		e1000_irq_disable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		e1000_irq_enable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	if ((adapter->hw.mng_cookie.status &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	    (vid == adapter->mng_vlan_id)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		/* release control to f/w */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		e1000_release_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	/* remove VID from filter table */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		index = (vid >> 5) & 0x7F;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		vfta &= ~(1 << (vid & 0x1F));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		hw->mac.ops.write_vfta(hw, index, vfta);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	u16 vid = adapter->hw.mng_cookie.vlan_id;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	u16 old_vid = adapter->mng_vlan_id;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
	if (!adapter->vlgrp)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	if (!vlan_group_get_device(adapter->vlgrp, vid)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
		if (adapter->hw.mng_cookie.status &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
			e1000_vlan_rx_add_vid(netdev, vid);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
			adapter->mng_vlan_id = vid;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
				(vid != old_vid) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
		    !vlan_group_get_device(adapter->vlgrp, old_vid))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
			e1000_vlan_rx_kill_vid(netdev, old_vid);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
		adapter->mng_vlan_id = vid;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
static void e1000_vlan_rx_register(struct net_device *netdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
				   struct vlan_group *grp)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	u32 ctrl, rctl;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
		e1000_irq_disable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	adapter->vlgrp = grp;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	if (grp) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		/* enable VLAN tag insert/strip */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		ctrl = er32(CTRL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		ctrl |= E1000_CTRL_VME;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
		ew32(CTRL, ctrl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
			/* enable VLAN receive filtering */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
			rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
			rctl &= ~E1000_RCTL_CFIEN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
			ew32(RCTL, rctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
			e1000_update_mng_vlan(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
		/* disable VLAN tag insert/strip */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
		ctrl = er32(CTRL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
		ctrl &= ~E1000_CTRL_VME;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
		ew32(CTRL, ctrl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
			if (adapter->mng_vlan_id !=
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			    (u16)E1000_MNG_VLAN_NONE) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
				e1000_vlan_rx_kill_vid(netdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
						       adapter->mng_vlan_id);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
		e1000_irq_enable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
static void e1000_restore_vlan(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	u16 vid;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	if (!adapter->vlgrp)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	for (vid = 0; vid < VLAN_N_VID; vid++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
		if (!vlan_group_get_device(adapter->vlgrp, vid))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
			continue;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
		e1000_vlan_rx_add_vid(adapter->netdev, vid);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
	u32 manc, manc2h, mdef, i, j;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
	manc = er32(MANC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
	 * enable receiving management packets to the host. this will probably
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
	 * generate destination unreachable messages from the host OS, but
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	 * the packets will be handled on SMBUS
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	manc |= E1000_MANC_EN_MNG2HOST;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
	manc2h = er32(MANC2H);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
	switch (hw->mac.type) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
		manc2h |= (E1000_MANC2H_PORT_623 | E1000_MANC2H_PORT_664);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	case e1000_82574:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	case e1000_82583:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		 * Check if IPMI pass-through decision filter already exists;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
		 * if so, enable it.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
		for (i = 0, j = 0; i < 8; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
			mdef = er32(MDEF(i));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			/* Ignore filters with anything other than IPMI ports */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
			if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
				continue;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
			/* Enable this decision filter in MANC2H */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
			if (mdef)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
				manc2h |= (1 << i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
			j |= mdef;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
		if (j == (E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
		/* Create new decision filter in an empty filter */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
		for (i = 0, j = 0; i < 8; i++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
			if (er32(MDEF(i)) == 0) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
				ew32(MDEF(i), (E1000_MDEF_PORT_623 |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
					       E1000_MDEF_PORT_664));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
				manc2h |= (1 << 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
				j++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
				break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		if (!j)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
			e_warn("Unable to create IPMI pass-through filter\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
	ew32(MANC2H, manc2h);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
	ew32(MANC, manc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
 * Configure the Tx unit of the MAC after a reset.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
static void e1000_configure_tx(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
	u64 tdba;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
	u32 tdlen, tctl, tipg, tarc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
	u32 ipgr1, ipgr2;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	/* Setup the HW Tx Head and Tail descriptor pointers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	tdba = tx_ring->dma;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	ew32(TDBAH, (tdba >> 32));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	ew32(TDLEN, tdlen);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	ew32(TDH, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
	ew32(TDT, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	tx_ring->head = E1000_TDH;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	tx_ring->tail = E1000_TDT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	/* Set the default values for the Tx Inter Packet Gap timer */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	tipg = DEFAULT_82543_TIPG_IPGT_COPPER;          /*  8  */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
	ipgr1 = DEFAULT_82543_TIPG_IPGR1;               /*  8  */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
	ipgr2 = DEFAULT_82543_TIPG_IPGR2;               /*  6  */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
	if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /*  7  */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
	ew32(TIPG, tipg);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	/* Set the Tx Interrupt Delay register */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	ew32(TIDV, adapter->tx_int_delay);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	/* Tx irq moderation */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
	ew32(TADV, adapter->tx_abs_int_delay);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	if (adapter->flags2 & FLAG2_DMA_BURST) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
		u32 txdctl = er32(TXDCTL(0));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
			    E1000_TXDCTL_WTHRESH);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		 * set up some performance related parameters to encourage the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		 * hardware to use the bus more efficiently in bursts, depends
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
		 * on the tx_int_delay to be enabled,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		 * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
		 * hthresh = 1 ==> prefetch when one or more available
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
		 * pthresh = 0x1f ==> prefetch if internal cache 31 or less
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
		 * BEWARE: this seems to work but should be considered first if
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		 * there are tx hangs or other tx related bugs
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
		txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		ew32(TXDCTL(0), txdctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		/* erratum work around: set txdctl the same for both queues */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
		ew32(TXDCTL(1), txdctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	/* Program the Transmit Control Register */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	tctl = er32(TCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	tctl &= ~E1000_TCTL_CT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
		tarc = er32(TARC(0));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
		 * set the speed mode bit, we'll clear it if we're not at
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
		 * gigabit link later
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
#define SPEED_MODE_BIT (1 << 21)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		tarc |= SPEED_MODE_BIT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
		ew32(TARC(0), tarc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	/* errata: program both queues to unweighted RR */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		tarc = er32(TARC(0));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		tarc |= 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
		ew32(TARC(0), tarc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		tarc = er32(TARC(1));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		tarc |= 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
		ew32(TARC(1), tarc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	/* Setup Transmit Descriptor Settings for eop descriptor */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
	/* only set IDE if we are delaying interrupts using the timers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
	if (adapter->tx_int_delay)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	/* enable Report Status bit */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	ew32(TCTL, tctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	e1000e_config_collision_dist(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
 * e1000_setup_rctl - configure the receive control registers
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
 * @adapter: Board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
static void e1000_setup_rctl(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
	u32 rctl, rfctl;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
	u32 psrctl = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
	u32 pages = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	/* Workaround Si errata on 82579 - configure jumbo frame flow */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
	if (hw->mac.type == e1000_pch2lan) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
		s32 ret_val;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		if (adapter->netdev->mtu > ETH_DATA_LEN)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
		else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	/* Program MC offset vector base */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
		(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	/* Do not Store bad packets */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	rctl &= ~E1000_RCTL_SBP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	/* Enable Long Packet receive */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
		rctl &= ~E1000_RCTL_LPE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
		rctl |= E1000_RCTL_LPE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	/* Some systems expect that the CRC is included in SMBUS traffic. The
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	 * hardware strips the CRC before sending to both SMBUS (BMC) and to
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
	 * host memory when this is enabled
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		rctl |= E1000_RCTL_SECRC;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
	if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		u16 phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		phy_data &= 0xfff8;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		phy_data |= (1 << 2);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		e1e_wphy(hw, PHY_REG(770, 26), phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		e1e_rphy(hw, 22, &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		phy_data &= 0x0fff;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		phy_data |= (1 << 14);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		e1e_wphy(hw, 0x10, 0x2823);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		e1e_wphy(hw, 0x11, 0x0003);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
		e1e_wphy(hw, 22, phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	/* Setup buffer sizes */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	rctl &= ~E1000_RCTL_SZ_4096;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	rctl |= E1000_RCTL_BSEX;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
	switch (adapter->rx_buffer_len) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	case 2048:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		rctl |= E1000_RCTL_SZ_2048;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		rctl &= ~E1000_RCTL_BSEX;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
	case 4096:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
		rctl |= E1000_RCTL_SZ_4096;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
	case 8192:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
		rctl |= E1000_RCTL_SZ_8192;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
	case 16384:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		rctl |= E1000_RCTL_SZ_16384;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
	 * 82571 and greater support packet-split where the protocol
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	 * header is placed in skb->data and the packet data is
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
	 * In the case of a non-split, skb->data is linearly filled,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	 * followed by the page buffers.  Therefore, skb->data is
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
	 * sized to hold the largest protocol header.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
	 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	 * allocations using alloc_page take too long for regular MTU
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	 * so only enable packet split for jumbo frames
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	 * Using pages when the page size is greater than 16k wastes
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	 * a lot of memory, since we allocate 3 pages at all times
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	 * per packet.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	if (!(adapter->flags & FLAG_HAS_ERT) && (pages <= 3) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	    (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
		adapter->rx_ps_pages = pages;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		adapter->rx_ps_pages = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
	if (adapter->rx_ps_pages) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		/* Configure extra packet-split registers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
		rfctl = er32(RFCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
		rfctl |= E1000_RFCTL_EXTEN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
		 * disable packet split support for IPv6 extension headers,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		 * because some malformed IPv6 headers can hang the Rx
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
			  E1000_RFCTL_NEW_IPV6_EXT_DIS);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		ew32(RFCTL, rfctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
		/* Enable Packet split descriptors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		rctl |= E1000_RCTL_DTYP_PS;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
		psrctl |= adapter->rx_ps_bsize0 >>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
			E1000_PSRCTL_BSIZE0_SHIFT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		switch (adapter->rx_ps_pages) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
		case 3:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
			psrctl |= PAGE_SIZE <<
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
				E1000_PSRCTL_BSIZE3_SHIFT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		case 2:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
			psrctl |= PAGE_SIZE <<
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
				E1000_PSRCTL_BSIZE2_SHIFT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
		case 1:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
			psrctl |= PAGE_SIZE >>
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
				E1000_PSRCTL_BSIZE1_SHIFT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
		ew32(PSRCTL, psrctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	ew32(RCTL, rctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	/* just started the receive unit, no need to restart */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	adapter->flags &= ~FLAG_RX_RESTART_NOW;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
 * e1000_configure_rx - Configure Receive Unit after Reset
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
 * Configure the Rx unit of the MAC after a reset.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
static void e1000_configure_rx(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	struct e1000_ring *rx_ring = adapter->rx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	u64 rdba;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
	u32 rdlen, rctl, rxcsum, ctrl_ext;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	if (adapter->rx_ps_pages) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
		/* this is a 32 byte descriptor */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
		rdlen = rx_ring->count *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
			sizeof(union e1000_rx_desc_packet_split);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		adapter->clean_rx = e1000_clean_rx_irq_ps;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		adapter->clean_rx = e1000_clean_rx_irq;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	/* disable receives while setting up the descriptors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
	e1e_flush();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	msleep(10);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	if (adapter->flags2 & FLAG2_DMA_BURST) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
		 * set the writeback threshold (only takes effect if the RDTR
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		 * is set). set GRAN=1 and write back up to 0x4 worth, and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
		 * enable prefetching of 0x20 rx descriptors
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		 * granularity = 01
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
		 * wthresh = 04,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
		 * hthresh = 04,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
		 * pthresh = 0x20
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
		ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
		ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
		 * override the delay timers for enabling bursting, only if
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
		 * the value was not set by the user via module options
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
		if (adapter->rx_int_delay == DEFAULT_RDTR)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
			adapter->rx_int_delay = BURST_RDTR;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		if (adapter->rx_abs_int_delay == DEFAULT_RADV)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
			adapter->rx_abs_int_delay = BURST_RADV;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	/* set the Receive Delay Timer Register */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	ew32(RDTR, adapter->rx_int_delay);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	/* irq moderation */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	ew32(RADV, adapter->rx_abs_int_delay);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	if ((adapter->itr_setting != 0) && (adapter->itr != 0))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
		ew32(ITR, 1000000000 / (adapter->itr * 256));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
	ctrl_ext = er32(CTRL_EXT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	/* Auto-Mask interrupts upon ICR access */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	ctrl_ext |= E1000_CTRL_EXT_IAME;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
	ew32(IAM, 0xffffffff);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
	ew32(CTRL_EXT, ctrl_ext);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	e1e_flush();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	 * Setup the HW Rx Head and Tail Descriptor Pointers and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	 * the Base and Length of the Rx Descriptor Ring
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	rdba = rx_ring->dma;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	ew32(RDBAH, (rdba >> 32));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	ew32(RDLEN, rdlen);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	ew32(RDH, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	ew32(RDT, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	rx_ring->head = E1000_RDH;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	rx_ring->tail = E1000_RDT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	/* Enable Receive Checksum Offload for TCP and UDP */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	rxcsum = er32(RXCSUM);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	if (adapter->flags & FLAG_RX_CSUM_ENABLED) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
		rxcsum |= E1000_RXCSUM_TUOFL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
		 * IPv4 payload checksum for UDP fragments must be
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
		 * used in conjunction with packet-split.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
		if (adapter->rx_ps_pages)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
			rxcsum |= E1000_RXCSUM_IPPCSE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
		rxcsum &= ~E1000_RXCSUM_TUOFL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		/* no need to clear IPPCSE as it defaults to 0 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	ew32(RXCSUM, rxcsum);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	 * Enable early receives on supported devices, only takes effect when
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	 * packet size is equal or larger than the specified value (in 8 byte
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	if ((adapter->flags & FLAG_HAS_ERT) ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	    (adapter->hw.mac.type == e1000_pch2lan)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
			u32 rxdctl = er32(RXDCTL(0));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
			ew32(RXDCTL(0), rxdctl | 0x3);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
			if (adapter->flags & FLAG_HAS_ERT)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
				ew32(ERT, E1000_ERT_2048 | (1 << 13));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
			 * With jumbo frames and early-receive enabled,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
			 * excessive C-state transition latencies result in
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
			 * dropped transactions.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
			pm_qos_update_request(
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
				&adapter->netdev->pm_qos_req, 55);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
			pm_qos_update_request(
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
				&adapter->netdev->pm_qos_req,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
				PM_QOS_DEFAULT_VALUE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
	/* Enable Receives */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	ew32(RCTL, rctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
 *  e1000_update_mc_addr_list - Update Multicast addresses
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
 *  @hw: pointer to the HW structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
 *  @mc_addr_list: array of multicast addresses to program
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
 *  @mc_addr_count: number of multicast addresses to program
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
 *  Updates the Multicast Table Array.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
 *  The caller must have a packed mc_addr_list of multicast addresses.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
				      u32 mc_addr_count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
 * e1000_set_multi - Multicast and Promiscuous mode set
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
 * @netdev: network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
 * The set_multi entry point is called whenever the multicast address
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
 * list or the network interface flags are updated.  This routine is
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
 * responsible for configuring the hardware for proper multicast,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
 * promiscuous mode, and all-multi behavior.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
static void e1000_set_multi(struct net_device *netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
	struct netdev_hw_addr *ha;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
	u8  *mta_list;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	u32 rctl;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
	int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
	/* Check for Promiscuous and All Multicast modes */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	if (netdev->flags & IFF_PROMISC) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
		rctl &= ~E1000_RCTL_VFE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		if (netdev->flags & IFF_ALLMULTI) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
			rctl |= E1000_RCTL_MPE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
			rctl &= ~E1000_RCTL_UPE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
			rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
			rctl |= E1000_RCTL_VFE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	ew32(RCTL, rctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
	if (!netdev_mc_empty(netdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
		mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		if (!mta_list)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
			return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
		/* prepare a packed array of only addresses. */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
		i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
		netdev_for_each_mc_addr(ha, netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
			memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
		e1000_update_mc_addr_list(hw, mta_list, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		kfree(mta_list);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
		 * if we're called from probe, we might not have
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
		 * anything to do here, so clear out the list
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
		e1000_update_mc_addr_list(hw, NULL, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 * e1000_configure - configure the hardware for Rx and Tx
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
 * @adapter: private board structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
static void e1000_configure(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	e1000_set_multi(adapter->netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
	e1000_restore_vlan(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	e1000_init_manageability_pt(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	e1000_configure_tx(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
	e1000_setup_rctl(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	e1000_configure_rx(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
 * e1000e_power_up_phy - restore link in case the phy was powered down
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
 * @adapter: address of board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
 * The phy may be powered down to save power and turn off link when the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
 * driver is unloaded and wake on lan is not enabled (among others)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
 * *** this routine MUST be followed by a call to e1000e_reset ***
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
void e1000e_power_up_phy(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	if (adapter->hw.phy.ops.power_up)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
		adapter->hw.phy.ops.power_up(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	adapter->hw.mac.ops.setup_link(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
 * e1000_power_down_phy - Power down the PHY
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
 * Power down the PHY so no link is implied when interface is down.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
 * The PHY cannot be powered down if management or WoL is active.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
static void e1000_power_down_phy(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	/* WoL is enabled */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	if (adapter->wol)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	if (adapter->hw.phy.ops.power_down)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
		adapter->hw.phy.ops.power_down(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
 * e1000e_reset - bring the hardware into a known good state
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
 * This function boots the hardware and enables some settings that
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
 * require a configuration cycle of the hardware - those cannot be
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
 * set/changed during runtime. After reset the device needs to be
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
 * properly configured for Rx, Tx etc.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
void e1000e_reset(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	struct e1000_mac_info *mac = &adapter->hw.mac;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	struct e1000_fc_info *fc = &adapter->hw.fc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
	u32 tx_space, min_tx_space, min_rx_space;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	u32 pba = adapter->pba;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	u16 hwm;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	/* reset Packet Buffer Allocation to default */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	ew32(PBA, pba);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		 * To maintain wire speed transmits, the Tx FIFO should be
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		 * large enough to accommodate two full transmit packets,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		 * the Rx FIFO should be large enough to accommodate at least
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
		 * one full receive packet and is similarly rounded up and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		 * expressed in KB.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		pba = er32(PBA);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		/* upper 16 bits has Tx packet buffer allocation size in KB */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		tx_space = pba >> 16;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		/* lower 16 bits has Rx packet buffer allocation size in KB */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		pba &= 0xffff;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
		 * the Tx fifo also stores 16 bytes of information about the tx
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
		 * but don't include ethernet FCS because hardware appends it
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
		min_tx_space = (adapter->max_frame_size +
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
				sizeof(struct e1000_tx_desc) -
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
				ETH_FCS_LEN) * 2;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
		min_tx_space = ALIGN(min_tx_space, 1024);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
		min_tx_space >>= 10;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
		/* software strips receive CRC, so leave room for it */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
		min_rx_space = adapter->max_frame_size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
		min_rx_space = ALIGN(min_rx_space, 1024);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		min_rx_space >>= 10;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
		 * If current Tx allocation is less than the min Tx FIFO size,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
		 * and the min Tx FIFO size is less than the current Rx FIFO
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
		 * allocation, take space away from current Rx allocation
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
		if ((tx_space < min_tx_space) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
		    ((min_tx_space - tx_space) < pba)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
			pba -= min_tx_space - tx_space;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
			 * if short on Rx space, Rx wins and must trump tx
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
			 * adjustment or use Early Receive if available
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
			if ((pba < min_rx_space) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
			    (!(adapter->flags & FLAG_HAS_ERT)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
				/* ERT enabled in e1000_configure_rx */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
				pba = min_rx_space;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
		ew32(PBA, pba);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
	 * flow control settings
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	 * The high water mark must be low enough to fit one full frame
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	 * (or the size used for early receive) above it in the Rx FIFO.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	 * Set it to the lower of:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	 * - 90% of the Rx FIFO size, and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	 * - the full Rx FIFO size minus the early receive size (for parts
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	 * - the full Rx FIFO size minus one full frame
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
		fc->pause_time = 0xFFFF;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
		fc->pause_time = E1000_FC_PAUSE_TIME;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
	fc->send_xon = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	fc->current_mode = fc->requested_mode;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	switch (hw->mac.type) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
		if ((adapter->flags & FLAG_HAS_ERT) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
		    (adapter->netdev->mtu > ETH_DATA_LEN))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
			hwm = min(((pba << 10) * 9 / 10),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
				  ((pba << 10) - (E1000_ERT_2048 << 3)));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
		else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
			hwm = min(((pba << 10) * 9 / 10),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
				  ((pba << 10) - adapter->max_frame_size));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
		fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
		fc->low_water = fc->high_water - 8;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	case e1000_pchlan:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
		 * Workaround PCH LOM adapter hangs with certain network
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		 * loads.  If hangs persist, try disabling Tx flow control.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
			fc->high_water = 0x3500;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
			fc->low_water  = 0x1500;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
			fc->high_water = 0x5000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
			fc->low_water  = 0x3000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
		fc->refresh_time = 0x1000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	case e1000_pch2lan:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
		fc->high_water = 0x05C20;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
		fc->low_water = 0x05048;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
		fc->pause_time = 0x0650;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
		fc->refresh_time = 0x0400;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
			pba = 14;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
			ew32(PBA, pba);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	 * Disable Adaptive Interrupt Moderation if 2 full packets cannot
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	 * fit in receive buffer and early-receive not supported.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
	if (adapter->itr_setting & 0x3) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
		if (((adapter->max_frame_size * 2) > (pba << 10)) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
		    !(adapter->flags & FLAG_HAS_ERT)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
			if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
				dev_info(&adapter->pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
					"Interrupt Throttle Rate turned off\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
				adapter->flags2 |= FLAG2_DISABLE_AIM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
				ew32(ITR, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
		} else if (adapter->flags2 & FLAG2_DISABLE_AIM) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
			dev_info(&adapter->pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
				 "Interrupt Throttle Rate turned on\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
			adapter->flags2 &= ~FLAG2_DISABLE_AIM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
			adapter->itr = 20000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
			ew32(ITR, 1000000000 / (adapter->itr * 256));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
	/* Allow time for pending master requests to run */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
	mac->ops.reset_hw(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	 * For parts with AMT enabled, let the firmware know
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	 * that the network interface is in control
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
	if (adapter->flags & FLAG_HAS_AMT)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
		e1000_get_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	ew32(WUC, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
	if (mac->ops.init_hw(hw))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
		e_err("Hardware Error\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	e1000_update_mng_vlan(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
	ew32(VET, ETH_P_8021Q);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	e1000e_reset_adaptive(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	e1000_get_phy_info(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
		u16 phy_data = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
		 * speed up time to link by disabling smart power down, ignore
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		 * the return value of this function because there is nothing
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
		 * different we would do if it failed
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
		phy_data &= ~IGP02E1000_PM_SPD;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
int e1000e_up(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	/* hardware has been reset, we need to reload some things */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	e1000_configure(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	clear_bit(__E1000_DOWN, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	napi_enable(&adapter->napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	if (adapter->msix_entries)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
		e1000_configure_msix(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
	e1000_irq_enable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
	netif_wake_queue(adapter->netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
	/* fire a link change interrupt to start the watchdog */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	if (adapter->msix_entries)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		ew32(ICS, E1000_ICS_LSC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
void e1000e_down(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
	u32 tctl, rctl;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	 * signal that we're down so the interrupt handler does not
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
	 * reschedule our watchdog timer
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
	set_bit(__E1000_DOWN, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	/* disable receives in the hardware */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	/* flush and sleep below */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	netif_stop_queue(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	/* disable transmits in the hardware */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	tctl = er32(TCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	tctl &= ~E1000_TCTL_EN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
	ew32(TCTL, tctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	/* flush both disables and wait for them to finish */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	e1e_flush();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
	msleep(10);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
	napi_disable(&adapter->napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	e1000_irq_disable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
	del_timer_sync(&adapter->watchdog_timer);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	del_timer_sync(&adapter->phy_info_timer);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
	netif_carrier_off(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
	adapter->link_speed = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	adapter->link_duplex = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	if (!pci_channel_offline(adapter->pdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
		e1000e_reset(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	e1000_clean_tx_ring(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	e1000_clean_rx_ring(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	 * TODO: for power management, we could drop the link and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	 * pci_disable_device here.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
void e1000e_reinit_locked(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	might_sleep();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
		msleep(1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	e1000e_down(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	e1000e_up(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	clear_bit(__E1000_RESETTING, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
 * @adapter: board private structure to initialize
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
 * e1000_sw_init initializes the Adapter private data structure.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
 * Fields are initialized based on PCI device information and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
 * OS network device settings (MTU size).
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
	adapter->rx_ps_bsize0 = 128;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
	e1000e_set_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	if (e1000_alloc_queues(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		return -ENOMEM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
	/* Explicitly disable IRQ since the NIC can be in any state. */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
	e1000_irq_disable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	set_bit(__E1000_DOWN, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
 * e1000_intr_msi_test - Interrupt Handler
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
 * @irq: interrupt number
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
 * @data: pointer to a network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
static irqreturn_t e1000_intr_msi_test(int irq, void *data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	struct net_device *netdev = data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	u32 icr = er32(ICR);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	e_dbg("icr is %08X\n", icr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	if (icr & E1000_ICR_RXSEQ) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
		wmb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	return IRQ_HANDLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
 * e1000_test_msi_interrupt - Returns 0 for successful test
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
 * @adapter: board private struct
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
 * code flow taken from tg3.c
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	int err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	/* poll_enable hasn't been called yet, so don't need disable */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	/* clear any pending events */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	er32(ICR);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
	/* free the real vector and request a test handler */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	e1000_free_irq(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	e1000e_reset_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
	/* Assume that the test fails, if it succeeds then the test
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	 * MSI irq handler will unset this flag */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	adapter->flags |= FLAG_MSI_TEST_FAILED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	err = pci_enable_msi(adapter->pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
		goto msi_test_failed;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
			  netdev->name, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	if (err) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
		pci_disable_msi(adapter->pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
		goto msi_test_failed;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	wmb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
	e1000_irq_enable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	/* fire an unusual interrupt on the test handler */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
	ew32(ICS, E1000_ICS_RXSEQ);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	e1e_flush();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
	msleep(50);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	e1000_irq_disable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	rmb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
		e_info("MSI interrupt test failed, using legacy interrupt.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	} else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
		e_dbg("MSI interrupt test succeeded!\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	free_irq(adapter->pdev->irq, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	pci_disable_msi(adapter->pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
msi_test_failed:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	e1000e_set_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	return e1000_request_irq(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
 * @adapter: board private struct
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
 * code flow taken from tg3.c, called with e1000 interrupts disabled.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
static int e1000_test_msi(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	int err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	u16 pci_cmd;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
	if (!(adapter->flags & FLAG_MSI_ENABLED))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	/* disable SERR in case the MSI write causes a master abort */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
	if (pci_cmd & PCI_COMMAND_SERR)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		pci_write_config_word(adapter->pdev, PCI_COMMAND,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
				      pci_cmd & ~PCI_COMMAND_SERR);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	err = e1000_test_msi_interrupt(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	/* re-enable SERR */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
	if (pci_cmd & PCI_COMMAND_SERR) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
		pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
		pci_cmd |= PCI_COMMAND_SERR;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
		pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
	return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
 * e1000_open - Called when a network interface is made active
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
 * @netdev: network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
 * Returns 0 on success, negative value on failure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
 * The open entry point is called when a network interface is made
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
 * active by the system (IFF_UP).  At this point all resources needed
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
 * for transmit and receive operations are allocated, the interrupt
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
 * handler is registered with the OS, the watchdog timer is started,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
 * and the stack is notified that the interface is ready.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
static int e1000_open(struct net_device *netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	int err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	/* disallow open during test */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
	if (test_bit(__E1000_TESTING, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
		return -EBUSY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	pm_runtime_get_sync(&pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
	netif_carrier_off(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	/* allocate transmit descriptors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	err = e1000e_setup_tx_resources(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
		goto err_setup_tx;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
	/* allocate receive descriptors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	err = e1000e_setup_rx_resources(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
		goto err_setup_rx;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	 * If AMT is enabled, let the firmware know that the network
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	 * interface is now open and reset the part to a known state.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
	if (adapter->flags & FLAG_HAS_AMT) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
		e1000_get_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
		e1000e_reset(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
	e1000e_power_up_phy(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	if ((adapter->hw.mng_cookie.status &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
		e1000_update_mng_vlan(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	/* DMA latency requirement to workaround early-receive/jumbo issue */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
	if ((adapter->flags & FLAG_HAS_ERT) ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	    (adapter->hw.mac.type == e1000_pch2lan))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
		pm_qos_add_request(&adapter->netdev->pm_qos_req,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
				   PM_QOS_CPU_DMA_LATENCY,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
				   PM_QOS_DEFAULT_VALUE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	 * before we allocate an interrupt, we must be ready to handle it.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
	 * as soon as we call pci_request_irq, so we have to setup our
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	 * clean_rx handler before we do so.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
	e1000_configure(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
	err = e1000_request_irq(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
		goto err_req_irq;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	 * Work around PCIe errata with MSI interrupts causing some chipsets to
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	 * ignore e1000e MSI messages, which means we need to test our MSI
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
	 * interrupt now
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
	if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
		err = e1000_test_msi(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
		if (err) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
			e_err("Interrupt allocation failed\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
			goto err_req_irq;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
	/* From here on the code is the same as e1000e_up() */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	clear_bit(__E1000_DOWN, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	napi_enable(&adapter->napi);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	e1000_irq_enable(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	netif_start_queue(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
	adapter->idle_check = true;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	pm_runtime_put(&pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	/* fire a link status change interrupt to start the watchdog */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	if (adapter->msix_entries)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
		ew32(ICS, E1000_ICS_LSC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
err_req_irq:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	e1000_release_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
	e1000_power_down_phy(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	e1000e_free_rx_resources(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
err_setup_rx:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
	e1000e_free_tx_resources(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
err_setup_tx:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
	e1000e_reset(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
	pm_runtime_put_sync(&pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
	return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
 * e1000_close - Disables a network interface
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
 * @netdev: network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
 * Returns 0, this is not allowed to fail
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
 * The close entry point is called when an interface is de-activated
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
 * by the OS.  The hardware is still under the drivers control, but
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
 * needs to be disabled.  A global MAC reset is issued to stop the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
 * hardware, and all transmit and receive resources are freed.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
static int e1000_close(struct net_device *netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	pm_runtime_get_sync(&pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	if (!test_bit(__E1000_DOWN, &adapter->state)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
		e1000e_down(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
		e1000_free_irq(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	e1000_power_down_phy(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
	e1000e_free_tx_resources(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
	e1000e_free_rx_resources(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	 * kill manageability vlan ID if supported, but not if a vlan with
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	 * the same ID is registered on the host OS (let 8021q kill it)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
	if ((adapter->hw.mng_cookie.status &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	     !(adapter->vlgrp &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	 * If AMT is enabled, let the firmware know that the network
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
	 * interface is now closed
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
	if (adapter->flags & FLAG_HAS_AMT)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
		e1000_release_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
	if ((adapter->flags & FLAG_HAS_ERT) ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	    (adapter->hw.mac.type == e1000_pch2lan))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
		pm_qos_remove_request(&adapter->netdev->pm_qos_req);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
	pm_runtime_put_sync(&pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
 * e1000_set_mac - Change the Ethernet Address of the NIC
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
 * @netdev: network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
 * @p: pointer to an address structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
 * Returns 0 on success, negative on failure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
static int e1000_set_mac(struct net_device *netdev, void *p)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
	struct sockaddr *addr = p;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
	if (!is_valid_ether_addr(addr->sa_data))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
		return -EADDRNOTAVAIL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
	e1000e_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
		/* activate the work around */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		e1000e_set_laa_state_82571(&adapter->hw, 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
		 * Hold a copy of the LAA in RAR[14] This is done so that
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
		 * between the time RAR[0] gets clobbered  and the time it
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
		 * of the RARs and no incoming packets directed to this port
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
		 * are dropped. Eventually the LAA will be in RAR[0] and
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
		 * RAR[14]
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
		e1000e_rar_set(&adapter->hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
			      adapter->hw.mac.addr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
			      adapter->hw.mac.rar_entry_count - 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
 * e1000e_update_phy_task - work thread to update phy
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
 * @work: pointer to our work struct
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
 * this worker thread exists because we must acquire a
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
 * semaphore to read the phy, which we could msleep while
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
 * waiting for it, and we can't msleep in a timer.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
static void e1000e_update_phy_task(struct work_struct *work)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
	struct e1000_adapter *adapter = container_of(work,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
					struct e1000_adapter, update_phy_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	e1000_get_phy_info(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
 * Need to wait a few seconds after link up to get diagnostic information from
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
 * the phy
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
static void e1000_update_phy_info(unsigned long data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	schedule_work(&adapter->update_phy_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
 * e1000e_update_phy_stats - Update the PHY statistics counters
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
static void e1000e_update_phy_stats(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	s32 ret_val;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	u16 phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	ret_val = hw->phy.ops.acquire(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	if (ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	hw->phy.addr = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
#define HV_PHY_STATS_PAGE	778
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
	 * A page set is expensive so check if already on desired page.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	 * If not, set to the page with the PHY status registers.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	ret_val = e1000e_read_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	if (ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		goto release;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
	if (phy_data != (HV_PHY_STATS_PAGE << IGP_PAGE_SHIFT)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
		ret_val = e1000e_write_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
						    IGP01E1000_PHY_PAGE_SELECT,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
						    (HV_PHY_STATS_PAGE <<
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
						     IGP_PAGE_SHIFT));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
		if (ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
			goto release;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
	/* Read/clear the upper 16-bit registers and read/accumulate lower */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
	/* Single Collision Count */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
	e1000e_read_phy_reg_mdic(hw, HV_SCC_UPPER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
				 &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
	ret_val = e1000e_read_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
					   HV_SCC_LOWER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
	if (!ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
		adapter->stats.scc += phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	/* Excessive Collision Count */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	e1000e_read_phy_reg_mdic(hw, HV_ECOL_UPPER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
				 &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
	ret_val = e1000e_read_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
					   HV_ECOL_LOWER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
	if (!ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
		adapter->stats.ecol += phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	/* Multiple Collision Count */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	e1000e_read_phy_reg_mdic(hw, HV_MCC_UPPER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
				 &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	ret_val = e1000e_read_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
					   HV_MCC_LOWER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	if (!ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
		adapter->stats.mcc += phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	/* Late Collision Count */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	e1000e_read_phy_reg_mdic(hw, HV_LATECOL_UPPER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
				 &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
	ret_val = e1000e_read_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
					   HV_LATECOL_LOWER &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
					   MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	if (!ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
		adapter->stats.latecol += phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
	/* Collision Count - also used for adaptive IFS */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	e1000e_read_phy_reg_mdic(hw, HV_COLC_UPPER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
				 &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
	ret_val = e1000e_read_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
					   HV_COLC_LOWER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
	if (!ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		hw->mac.collision_delta = phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
	/* Defer Count */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
	e1000e_read_phy_reg_mdic(hw, HV_DC_UPPER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
				 &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
	ret_val = e1000e_read_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
					   HV_DC_LOWER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
	if (!ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
		adapter->stats.dc += phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	/* Transmit with no CRS */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	e1000e_read_phy_reg_mdic(hw, HV_TNCRS_UPPER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
				 &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	ret_val = e1000e_read_phy_reg_mdic(hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
					   HV_TNCRS_LOWER & MAX_PHY_REG_ADDRESS,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
					   &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	if (!ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		adapter->stats.tncrs += phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
release:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	hw->phy.ops.release(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
 * e1000e_update_stats - Update the board statistics counters
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
void e1000e_update_stats(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
	 * Prevent stats update while adapter is being reset, or if the pci
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	 * connection is down.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
	if (adapter->link_speed == 0)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	if (pci_channel_offline(pdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
	adapter->stats.crcerrs += er32(CRCERRS);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	adapter->stats.gprc += er32(GPRC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
	adapter->stats.gorc += er32(GORCL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	er32(GORCH); /* Clear gorc */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	adapter->stats.bprc += er32(BPRC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	adapter->stats.mprc += er32(MPRC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	adapter->stats.roc += er32(ROC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	adapter->stats.mpc += er32(MPC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
	/* Half-duplex statistics */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	if (adapter->link_duplex == HALF_DUPLEX) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		if (adapter->flags2 & FLAG2_HAS_PHY_STATS) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
			e1000e_update_phy_stats(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
			adapter->stats.scc += er32(SCC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
			adapter->stats.ecol += er32(ECOL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
			adapter->stats.mcc += er32(MCC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
			adapter->stats.latecol += er32(LATECOL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
			adapter->stats.dc += er32(DC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
			hw->mac.collision_delta = er32(COLC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
			if ((hw->mac.type != e1000_82574) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
			    (hw->mac.type != e1000_82583))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
				adapter->stats.tncrs += er32(TNCRS);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
		adapter->stats.colc += hw->mac.collision_delta;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
	adapter->stats.xonrxc += er32(XONRXC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
	adapter->stats.xontxc += er32(XONTXC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	adapter->stats.xoffrxc += er32(XOFFRXC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
	adapter->stats.xofftxc += er32(XOFFTXC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
	adapter->stats.gptc += er32(GPTC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	adapter->stats.gotc += er32(GOTCL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
	er32(GOTCH); /* Clear gotc */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
	adapter->stats.rnbc += er32(RNBC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
	adapter->stats.ruc += er32(RUC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	adapter->stats.mptc += er32(MPTC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
	adapter->stats.bptc += er32(BPTC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	/* used for adaptive IFS */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	hw->mac.tx_packet_delta = er32(TPT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
	adapter->stats.tpt += hw->mac.tx_packet_delta;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	adapter->stats.algnerrc += er32(ALGNERRC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	adapter->stats.rxerrc += er32(RXERRC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	adapter->stats.cexterr += er32(CEXTERR);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	adapter->stats.tsctc += er32(TSCTC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
	adapter->stats.tsctfc += er32(TSCTFC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
	/* Fill out the OS statistics structure */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
	netdev->stats.multicast = adapter->stats.mprc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	netdev->stats.collisions = adapter->stats.colc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	/* Rx Errors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
	 * RLEC on some newer hardware can be incorrect so build
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
	 * our own version based on RUC and ROC
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
	netdev->stats.rx_errors = adapter->stats.rxerrc +
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
		adapter->stats.crcerrs + adapter->stats.algnerrc +
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
		adapter->stats.ruc + adapter->stats.roc +
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
		adapter->stats.cexterr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	netdev->stats.rx_length_errors = adapter->stats.ruc +
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
					      adapter->stats.roc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	/* Tx Errors */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
	netdev->stats.tx_errors = adapter->stats.ecol +
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
				       adapter->stats.latecol;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	netdev->stats.tx_window_errors = adapter->stats.latecol;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
	/* Tx Dropped needs to be maintained elsewhere */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
	/* Management Stats */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
	adapter->stats.mgptc += er32(MGTPTC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	adapter->stats.mgprc += er32(MGTPRC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
	adapter->stats.mgpdc += er32(MGTPDC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
 * e1000_phy_read_status - Update the PHY register status snapshot
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
 * @adapter: board private structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
static void e1000_phy_read_status(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	struct e1000_phy_regs *phy = &adapter->phy_regs;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
	int ret_val;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
	if ((er32(STATUS) & E1000_STATUS_LU) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
		ret_val  = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
		ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
		ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
		ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
		ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
		if (ret_val)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
			e_warn("Error reading PHY register\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
		 * Do not read PHY registers if link is not up
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
		 * Set values to typical power-on defaults
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
			     BMSR_ERCAP);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
				  ADVERTISE_ALL | ADVERTISE_CSMA);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
		phy->lpa = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
		phy->expansion = EXPANSION_ENABLENPAGE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
		phy->ctrl1000 = ADVERTISE_1000FULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
		phy->stat1000 = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
static void e1000_print_link_info(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	u32 ctrl = er32(CTRL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
	/* Link status message must follow this format for user tools */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	printk(KERN_INFO "e1000e: %s NIC Link is Up %d Mbps %s, "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
	       "Flow Control: %s\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	       adapter->netdev->name,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
	       adapter->link_speed,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	       (adapter->link_duplex == FULL_DUPLEX) ?
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	                        "Full Duplex" : "Half Duplex",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
	       ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	                        "RX/TX" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
	       ((ctrl & E1000_CTRL_RFCE) ? "RX" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	       ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
static bool e1000e_has_link(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	bool link_active = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
	s32 ret_val = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
	 * get_link_status is set on LSC (link status) interrupt or
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
	 * Rx sequence error interrupt.  get_link_status will stay
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
	 * false until the check_for_link establishes link
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
	 * for copper adapters ONLY
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	switch (hw->phy.media_type) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	case e1000_media_type_copper:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		if (hw->mac.get_link_status) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
			ret_val = hw->mac.ops.check_for_link(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
			link_active = !hw->mac.get_link_status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			link_active = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
	case e1000_media_type_fiber:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		ret_val = hw->mac.ops.check_for_link(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
	case e1000_media_type_internal_serdes:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
		ret_val = hw->mac.ops.check_for_link(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
		link_active = adapter->hw.mac.serdes_has_link;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
	case e1000_media_type_unknown:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
		e_info("Gigabit has been disabled, downgrading speed\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
	return link_active;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
static void e1000e_enable_receives(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	/* make sure the receive unit is started */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	    (adapter->flags & FLAG_RX_RESTART_NOW)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
		struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
		u32 rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
		ew32(RCTL, rctl | E1000_RCTL_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		adapter->flags &= ~FLAG_RX_RESTART_NOW;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
static void e1000e_check_82574_phy_workaround(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
	 * With 82574 controllers, PHY needs to be checked periodically
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	 * for hung state and reset, if two calls return true
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
	if (e1000_check_phy_82574(hw))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
		adapter->phy_hang_count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
		adapter->phy_hang_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	if (adapter->phy_hang_count > 1) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
		adapter->phy_hang_count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
		schedule_work(&adapter->reset_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
 * e1000_watchdog - Timer Call-back
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
 * @data: pointer to adapter cast into an unsigned long
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
static void e1000_watchdog(unsigned long data)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	/* Do the rest outside of interrupt context */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
	schedule_work(&adapter->watchdog_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	/* TODO: make this use queue_delayed_work() */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
static void e1000_watchdog_task(struct work_struct *work)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
	struct e1000_adapter *adapter = container_of(work,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
					struct e1000_adapter, watchdog_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
	struct e1000_mac_info *mac = &adapter->hw.mac;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
	struct e1000_phy_info *phy = &adapter->hw.phy;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
	u32 link, tctl;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
	int tx_pending = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
	link = e1000e_has_link(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	if ((netif_carrier_ok(netdev)) && link) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
		/* Cancel scheduled suspend requests. */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
		pm_runtime_resume(netdev->dev.parent);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
		e1000e_enable_receives(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
		goto link_up;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
		e1000_update_mng_vlan(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
	if (link) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
		if (!netif_carrier_ok(netdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
			bool txb2b = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
			/* Cancel scheduled suspend requests. */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
			pm_runtime_resume(netdev->dev.parent);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
			/* update snapshot of PHY registers on LSC */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
			e1000_phy_read_status(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
			mac->ops.get_link_up_info(&adapter->hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
						   &adapter->link_speed,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
						   &adapter->link_duplex);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
			e1000_print_link_info(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
			 * On supported PHYs, check for duplex mismatch only
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
			 * if link has autonegotiated at 10/100 half
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
			if ((hw->phy.type == e1000_phy_igp_3 ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
			     hw->phy.type == e1000_phy_bm) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
			    (hw->mac.autoneg == true) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
			    (adapter->link_speed == SPEED_10 ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			     adapter->link_speed == SPEED_100) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
			    (adapter->link_duplex == HALF_DUPLEX)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
				u16 autoneg_exp;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
				e1e_rphy(hw, PHY_AUTONEG_EXP, &autoneg_exp);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
				if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
					e_info("Autonegotiated half duplex but"
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
					       " link partner cannot autoneg. "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
					       " Try forcing full duplex if "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
					       "link gets many collisions.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
			/* adjust timeout factor according to speed/duplex */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
			adapter->tx_timeout_factor = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
			switch (adapter->link_speed) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
			case SPEED_10:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
				txb2b = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
				adapter->tx_timeout_factor = 16;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
				break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
			case SPEED_100:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
				txb2b = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
				adapter->tx_timeout_factor = 10;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
				break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
			 * workaround: re-program speed mode bit after
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
			 * link-up event
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
			    !txb2b) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
				u32 tarc0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
				tarc0 = er32(TARC(0));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
				tarc0 &= ~SPEED_MODE_BIT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
				ew32(TARC(0), tarc0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
			 * disable TSO for pcie and 10/100 speeds, to avoid
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
			 * some hardware issues
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
				switch (adapter->link_speed) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
				case SPEED_10:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
				case SPEED_100:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
					e_info("10/100 speed: disabling TSO\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
					netdev->features &= ~NETIF_F_TSO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
					netdev->features &= ~NETIF_F_TSO6;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
					break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
				case SPEED_1000:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
					netdev->features |= NETIF_F_TSO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
					netdev->features |= NETIF_F_TSO6;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
					break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
				default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
					/* oops */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
					break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
				}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
			 * enable transmits in the hardware, need to do this
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
			 * after setting TARC(0)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
			tctl = er32(TCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
			tctl |= E1000_TCTL_EN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
			ew32(TCTL, tctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
                        /*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
			 * Perform any post-link-up configuration before
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
			 * reporting link up.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
			if (phy->ops.cfg_on_link_up)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
				phy->ops.cfg_on_link_up(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
			netif_carrier_on(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
			if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
				mod_timer(&adapter->phy_info_timer,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
					  round_jiffies(jiffies + 2 * HZ));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
		if (netif_carrier_ok(netdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
			adapter->link_speed = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
			adapter->link_duplex = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
			/* Link status message must follow this format */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
			printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
			       adapter->netdev->name);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
			netif_carrier_off(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
			if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
				mod_timer(&adapter->phy_info_timer,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
					  round_jiffies(jiffies + 2 * HZ));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
			if (adapter->flags & FLAG_RX_NEEDS_RESTART)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
				schedule_work(&adapter->reset_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
			else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
				pm_schedule_suspend(netdev->dev.parent,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
							LINK_TIMEOUT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
link_up:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
	e1000e_update_stats(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
	adapter->tpt_old = adapter->stats.tpt;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	adapter->colc_old = adapter->stats.colc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
	adapter->gorc_old = adapter->stats.gorc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	adapter->gotc_old = adapter->stats.gotc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	e1000e_update_adaptive(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
	if (!netif_carrier_ok(netdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		tx_pending = (e1000_desc_unused(tx_ring) + 1 <
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
			       tx_ring->count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		if (tx_pending) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
			/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
			 * We've lost link, so the controller stops DMA,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
			 * but we've got queued Tx work that's never going
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
			 * to get done, so reset controller to flush Tx.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
			 * (Do the reset outside of interrupt context).
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
			 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
			adapter->tx_timeout_count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
			schedule_work(&adapter->reset_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
			/* return immediately since reset is imminent */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
			return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
	/* Simple mode for Interrupt Throttle Rate (ITR) */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	if (adapter->itr_setting == 4) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
		 * Total asymmetrical Tx or Rx gets ITR=8000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
		 * everyone else is between 2000-8000.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
		u32 goc = (adapter->gotc + adapter->gorc) / 10000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
		u32 dif = (adapter->gotc > adapter->gorc ?
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
			    adapter->gotc - adapter->gorc :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
			    adapter->gorc - adapter->gotc) / 10000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
		ew32(ITR, 1000000000 / (itr * 256));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	/* Cause software interrupt to ensure Rx ring is cleaned */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	if (adapter->msix_entries)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
		ew32(ICS, adapter->rx_ring->ims_val);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		ew32(ICS, E1000_ICS_RXDMT0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
	/* Force detection of hung controller every watchdog period */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
	adapter->detect_tx_hung = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
	/* flush partial descriptors to memory before detecting tx hang */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
	if (adapter->flags2 & FLAG2_DMA_BURST) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
		ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
		 * no need to flush the writes because the timeout code does
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		 * an er32 first thing
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
	 * With 82571 controllers, LAA may be overwritten due to controller
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
	 * reset from the other port. Set the appropriate LAA in RAR[0]
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	if (e1000e_get_laa_state_82571(hw))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
		e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	if (adapter->flags2 & FLAG2_CHECK_PHY_HANG)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
		e1000e_check_82574_phy_workaround(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
	/* Reset the timer */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
	if (!test_bit(__E1000_DOWN, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		mod_timer(&adapter->watchdog_timer,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
			  round_jiffies(jiffies + 2 * HZ));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
#define E1000_TX_FLAGS_CSUM		0x00000001
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
#define E1000_TX_FLAGS_VLAN		0x00000002
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
#define E1000_TX_FLAGS_TSO		0x00000004
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
#define E1000_TX_FLAGS_IPV4		0x00000008
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
#define E1000_TX_FLAGS_VLAN_SHIFT	16
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
static int e1000_tso(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
		     struct sk_buff *skb)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	struct e1000_context_desc *context_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	u32 cmd_length = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
	u16 ipcse = 0, tucse, mss;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	int err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	if (!skb_is_gso(skb))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
	if (skb_header_cloned(skb)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
			return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
	mss = skb_shinfo(skb)->gso_size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
	if (skb->protocol == htons(ETH_P_IP)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
		struct iphdr *iph = ip_hdr(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
		iph->tot_len = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
		iph->check = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
		                                         0, IPPROTO_TCP, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
		cmd_length = E1000_TXD_CMD_IP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
		ipcse = skb_transport_offset(skb) - 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	} else if (skb_is_gso_v6(skb)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
		ipv6_hdr(skb)->payload_len = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
		                                       &ipv6_hdr(skb)->daddr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		                                       0, IPPROTO_TCP, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
		ipcse = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
	ipcss = skb_network_offset(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	tucss = skb_transport_offset(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	tucse = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
	               E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	i = tx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	context_desc->lower_setup.ip_fields.ipcss  = ipcss;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	context_desc->lower_setup.ip_fields.ipcso  = ipcso;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	context_desc->upper_setup.tcp_fields.tucss = tucss;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
	context_desc->upper_setup.tcp_fields.tucso = tucso;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
	context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	buffer_info->time_stamp = jiffies;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
	buffer_info->next_to_watch = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
	i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
	if (i == tx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
	tx_ring->next_to_use = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	return 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	struct e1000_context_desc *context_desc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
	u8 css;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
	u32 cmd_len = E1000_TXD_CMD_DEXT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
	__be16 protocol;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
	if (skb->ip_summed != CHECKSUM_PARTIAL)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		protocol = skb->protocol;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	switch (protocol) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	case cpu_to_be16(ETH_P_IP):
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
			cmd_len |= E1000_TXD_CMD_TCP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	case cpu_to_be16(ETH_P_IPV6):
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
		/* XXX not handling all IPV6 headers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
			cmd_len |= E1000_TXD_CMD_TCP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		if (unlikely(net_ratelimit()))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
			e_warn("checksum_partial proto=%x!\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
			       be16_to_cpu(protocol));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
	css = skb_transport_offset(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
	i = tx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	context_desc->lower_setup.ip_config = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
	context_desc->upper_setup.tcp_fields.tucss = css;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	context_desc->upper_setup.tcp_fields.tucso =
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
				css + skb->csum_offset;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
	context_desc->upper_setup.tcp_fields.tucse = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	context_desc->tcp_seg_setup.data = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
	buffer_info->time_stamp = jiffies;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	buffer_info->next_to_watch = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	if (i == tx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
	tx_ring->next_to_use = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
	return 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
#define E1000_MAX_PER_TXD	8192
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
#define E1000_MAX_TXD_PWR	12
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
static int e1000_tx_map(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
			struct sk_buff *skb, unsigned int first,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
			unsigned int max_per_txd, unsigned int nr_frags,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
			unsigned int mss)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
	struct pci_dev *pdev = adapter->pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
	unsigned int len = skb_headlen(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	unsigned int offset = 0, size, count = 0, i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
	unsigned int f, bytecount, segs;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
	i = tx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	while (len) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
		buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
		size = min(len, max_per_txd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
		buffer_info->length = size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
		buffer_info->time_stamp = jiffies;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
		buffer_info->next_to_watch = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		buffer_info->dma = dma_map_single(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
						  skb->data + offset,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
						  size,	DMA_TO_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		buffer_info->mapped_as_page = false;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
			goto dma_error;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
		len -= size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
		offset += size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
		count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		if (len) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
			i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
			if (i == tx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
				i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	for (f = 0; f < nr_frags; f++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		struct skb_frag_struct *frag;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
		frag = &skb_shinfo(skb)->frags[f];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
		len = frag->size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
		offset = frag->page_offset;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
		while (len) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
			i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
			if (i == tx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
				i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
			buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
			size = min(len, max_per_txd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			buffer_info->length = size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			buffer_info->time_stamp = jiffies;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
			buffer_info->next_to_watch = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
							offset, size,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
							DMA_TO_DEVICE);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
			buffer_info->mapped_as_page = true;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
				goto dma_error;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
			len -= size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
			offset += size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
			count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
	segs = skb_shinfo(skb)->gso_segs ?: 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	/* multiply data chunks by size of headers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	tx_ring->buffer_info[i].skb = skb;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
	tx_ring->buffer_info[i].segs = segs;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	tx_ring->buffer_info[i].bytecount = bytecount;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	tx_ring->buffer_info[first].next_to_watch = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	return count;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
dma_error:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
	dev_err(&pdev->dev, "TX DMA map failed\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
	buffer_info->dma = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	if (count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
		count--;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
	while (count--) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		if (i==0)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
			i += tx_ring->count;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
		i--;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
		buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
		e1000_put_txbuf(adapter, buffer_info);;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
static void e1000_tx_queue(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
			   int tx_flags, int count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	struct e1000_tx_desc *tx_desc = NULL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
	struct e1000_buffer *buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	unsigned int i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	if (tx_flags & E1000_TX_FLAGS_TSO) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
			     E1000_TXD_CMD_TSE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
		if (tx_flags & E1000_TX_FLAGS_IPV4)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		txd_lower |= E1000_TXD_CMD_VLE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	i = tx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	while (count--) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		buffer_info = &tx_ring->buffer_info[i];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
		tx_desc = E1000_TX_DESC(*tx_ring, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		tx_desc->lower.data =
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
			cpu_to_le32(txd_lower | buffer_info->length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		tx_desc->upper.data = cpu_to_le32(txd_upper);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
		i++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
		if (i == tx_ring->count)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
			i = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
	 * Force memory writes to complete before letting h/w
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	 * know there are new descriptors to fetch.  (Only
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
	 * applicable for weak-ordered memory model archs,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
	 * such as IA-64).
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	wmb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	tx_ring->next_to_use = i;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	writel(i, adapter->hw.hw_addr + tx_ring->tail);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	 * we need this if more than one processor can write to our tail
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
	 * at a time, it synchronizes IO on IA64/Altix systems
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
	mmiowb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
#define MINIMUM_DHCP_PACKET_SIZE 282
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
				    struct sk_buff *skb)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	struct e1000_hw *hw =  &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
	u16 length, offset;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	if (vlan_tx_tag_present(skb)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
		    (adapter->hw.mng_cookie.status &
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
			return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
		const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
		struct udphdr *udp;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
		if (ip->protocol != IPPROTO_UDP)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
			return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
		if (ntohs(udp->dest) != 67)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
			return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
		offset = (u8 *)udp + 8 - skb->data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
		length = skb->len - offset;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
		return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	netif_stop_queue(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	 * Herbert's original patch had:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	 *  smp_mb__after_netif_stop_queue();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	 * but since that doesn't exist yet, just open code it.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
	smp_mb();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
	 * We need to check again in a case another CPU has just
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
	 * made room available.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
	if (e1000_desc_unused(adapter->tx_ring) < size)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
		return -EBUSY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	/* A reprieve! */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	netif_start_queue(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	++adapter->restart_queue;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
static int e1000_maybe_stop_tx(struct net_device *netdev, int size)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
	if (e1000_desc_unused(adapter->tx_ring) >= size)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	return __e1000_maybe_stop_tx(netdev, size);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
				    struct net_device *netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	struct e1000_ring *tx_ring = adapter->tx_ring;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	unsigned int first;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	unsigned int max_per_txd = E1000_MAX_PER_TXD;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	unsigned int tx_flags = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	unsigned int len = skb_headlen(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
	unsigned int nr_frags;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
	unsigned int mss;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	int count = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	int tso;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
	unsigned int f;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
	if (test_bit(__E1000_DOWN, &adapter->state)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
		dev_kfree_skb_any(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
		return NETDEV_TX_OK;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
	if (skb->len <= 0) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
		dev_kfree_skb_any(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
		return NETDEV_TX_OK;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
	mss = skb_shinfo(skb)->gso_size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	 * The controller does a simple calculation to
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	 * make sure there is enough room in the FIFO before
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	 * initiating the DMA for each buffer.  The calc is:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	 * 4 = ceil(buffer len/mss).  To make sure we don't
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	 * overrun the FIFO, adjust the max buffer len if mss
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
	 * drops.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
	if (mss) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
		u8 hdr_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
		max_per_txd = min(mss << 2, max_per_txd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
		max_txd_pwr = fls(max_per_txd) - 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
		 * TSO Workaround for 82571/2/3 Controllers -- if skb->data
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
		 * points to just header, pull a few bytes of payload from
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
		 * frags into skb->data
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
		/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
		 * we do this workaround for ES2LAN, but it is un-necessary,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
		 * avoiding it could save a lot of cycles
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
		 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
		if (skb->data_len && (hdr_len == len)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
			unsigned int pull_size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
			pull_size = min((unsigned int)4, skb->data_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
			if (!__pskb_pull_tail(skb, pull_size)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
				e_err("__pskb_pull_tail failed.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
				dev_kfree_skb_any(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
				return NETDEV_TX_OK;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
			len = skb_headlen(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
	/* reserve a descriptor for the offload context */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
		count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
	count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	count += TXD_USE_COUNT(len, max_txd_pwr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	nr_frags = skb_shinfo(skb)->nr_frags;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	for (f = 0; f < nr_frags; f++)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
				       max_txd_pwr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
	if (adapter->hw.mac.tx_pkt_filtering)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
		e1000_transfer_dhcp_info(adapter, skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
	 * need: count + 2 desc gap to keep tail from touching
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
	 * head, otherwise try next time
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	if (e1000_maybe_stop_tx(netdev, count + 2))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
		return NETDEV_TX_BUSY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	if (vlan_tx_tag_present(skb)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
		tx_flags |= E1000_TX_FLAGS_VLAN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
	first = tx_ring->next_to_use;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
	tso = e1000_tso(adapter, skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
	if (tso < 0) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
		dev_kfree_skb_any(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
		return NETDEV_TX_OK;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	if (tso)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
		tx_flags |= E1000_TX_FLAGS_TSO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
	else if (e1000_tx_csum(adapter, skb))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
		tx_flags |= E1000_TX_FLAGS_CSUM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
	 * Old method was to assume IPv4 packet by default if TSO was enabled.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
	 * no longer assume, we must.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	if (skb->protocol == htons(ETH_P_IP))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
		tx_flags |= E1000_TX_FLAGS_IPV4;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	/* if count is 0 then mapping error has occured */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	if (count) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
		e1000_tx_queue(adapter, tx_flags, count);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
		/* Make sure there is space in the ring for the next send. */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
		e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
		dev_kfree_skb_any(skb);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		tx_ring->buffer_info[first].time_stamp = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
		tx_ring->next_to_use = first;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	return NETDEV_TX_OK;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
 * e1000_tx_timeout - Respond to a Tx Hang
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
 * @netdev: network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
static void e1000_tx_timeout(struct net_device *netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
	/* Do the reset outside of interrupt context */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
	adapter->tx_timeout_count++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
	schedule_work(&adapter->reset_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
static void e1000_reset_task(struct work_struct *work)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
	struct e1000_adapter *adapter;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	adapter = container_of(work, struct e1000_adapter, reset_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
	if (!((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
	      (adapter->flags & FLAG_RX_RESTART_NOW))) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
		e1000e_dump(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
		e_err("Reset adapter\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
	e1000e_reinit_locked(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
 * e1000_get_stats - Get System Network Statistics
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
 * @netdev: network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
 * Returns the address of the device statistics structure.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
 * The statistics are actually updated from the timer callback.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
	/* only return the current stats */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	return &netdev->stats;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
 * e1000_change_mtu - Change the Maximum Transfer Unit
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
 * @netdev: network interface device structure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
 * @new_mtu: new value for maximum frame size
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
 * Returns 0 on success, negative on failure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
	/* Jumbo frame support */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
		e_err("Jumbo Frames not supported.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
		return -EINVAL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
	/* Supported frame sizes */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
	    (max_frame > adapter->max_hw_frame_size)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
		e_err("Unsupported MTU setting\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
		return -EINVAL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
	/* Jumbo frame workaround on 82579 requires CRC be stripped */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
	if ((adapter->hw.mac.type == e1000_pch2lan) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	    !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	    (new_mtu > ETH_DATA_LEN)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
		e_err("Jumbo Frames not supported on 82579 when CRC "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
		      "stripping is disabled.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
		return -EINVAL;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
	/* 82573 Errata 17 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
	if (((adapter->hw.mac.type == e1000_82573) ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
	     (adapter->hw.mac.type == e1000_82574)) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
	    (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
		adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
		e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
		msleep(1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
	adapter->max_frame_size = max_frame;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	netdev->mtu = new_mtu;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
	if (netif_running(netdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
		e1000e_down(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
	 * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
	 * means we reserve 2 more, this pushes us to allocate from the next
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
	 * larger slab size.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
	 * i.e. RXBUFFER_2048 --> size-4096 slab
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
	 * However with the new *_jumbo_rx* routines, jumbo receives will use
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
	 * fragmented skbs
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	if (max_frame <= 2048)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
		adapter->rx_buffer_len = 2048;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
		adapter->rx_buffer_len = 4096;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
	/* adjust allocation if LPE protects us, and we aren't using SBP */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
	     (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
					 + ETH_FCS_LEN;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
	if (netif_running(netdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
		e1000e_up(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
	else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
		e1000e_reset(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
	clear_bit(__E1000_RESETTING, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
			   int cmd)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
	struct mii_ioctl_data *data = if_mii(ifr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
	if (adapter->hw.phy.media_type != e1000_media_type_copper)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
		return -EOPNOTSUPP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
	switch (cmd) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	case SIOCGMIIPHY:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
		data->phy_id = adapter->hw.phy.addr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
	case SIOCGMIIREG:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
		e1000_phy_read_status(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
		switch (data->reg_num & 0x1F) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
		case MII_BMCR:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
			data->val_out = adapter->phy_regs.bmcr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
		case MII_BMSR:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
			data->val_out = adapter->phy_regs.bmsr;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
		case MII_PHYSID1:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
			data->val_out = (adapter->hw.phy.id >> 16);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
		case MII_PHYSID2:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
			data->val_out = (adapter->hw.phy.id & 0xFFFF);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
		case MII_ADVERTISE:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
			data->val_out = adapter->phy_regs.advertise;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
		case MII_LPA:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
			data->val_out = adapter->phy_regs.lpa;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
		case MII_EXPANSION:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
			data->val_out = adapter->phy_regs.expansion;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
		case MII_CTRL1000:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
			data->val_out = adapter->phy_regs.ctrl1000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
		case MII_STAT1000:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
			data->val_out = adapter->phy_regs.stat1000;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
		case MII_ESTATUS:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
			data->val_out = adapter->phy_regs.estatus;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
		default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
			return -EIO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
		break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	case SIOCSMIIREG:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
		return -EOPNOTSUPP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
	switch (cmd) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
	case SIOCGMIIPHY:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
	case SIOCGMIIREG:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	case SIOCSMIIREG:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
		return e1000_mii_ioctl(netdev, ifr, cmd);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
	default:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
		return -EOPNOTSUPP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
	u32 i, mac_reg;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
	u16 phy_reg;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
	int retval = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
	/* copy MAC RARs to PHY RARs */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
	e1000_copy_rx_addrs_to_phy_ich8lan(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
	/* copy MAC MTA to PHY MTA */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
		mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
		e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
		e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
	/* configure PHY Rx Control register */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
	e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	mac_reg = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
	if (mac_reg & E1000_RCTL_UPE)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
		phy_reg |= BM_RCTL_UPE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
	if (mac_reg & E1000_RCTL_MPE)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
		phy_reg |= BM_RCTL_MPE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
	phy_reg &= ~(BM_RCTL_MO_MASK);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
	if (mac_reg & E1000_RCTL_MO_3)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
		phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
				<< BM_RCTL_MO_SHIFT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
	if (mac_reg & E1000_RCTL_BAM)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		phy_reg |= BM_RCTL_BAM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
	if (mac_reg & E1000_RCTL_PMCF)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
		phy_reg |= BM_RCTL_PMCF;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
	mac_reg = er32(CTRL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
	if (mac_reg & E1000_CTRL_RFCE)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		phy_reg |= BM_RCTL_RFCE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
	e1e_wphy(&adapter->hw, BM_RCTL, phy_reg);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
	/* enable PHY wakeup in MAC register */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	ew32(WUFC, wufc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
	/* configure and enable PHY wakeup in PHY registers */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
	e1e_wphy(&adapter->hw, BM_WUFC, wufc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
	e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	/* activate PHY wakeup */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	retval = hw->phy.ops.acquire(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	if (retval) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
		e_err("Could not acquire PHY\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
		return retval;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	                         (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
	retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	if (retval) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
		e_err("Could not read PHY page 769\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
		goto out;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
	retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
	if (retval)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
		e_err("Could not set PHY Host Wakeup bit\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
out:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
	hw->phy.ops.release(hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
	return retval;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
			    bool runtime)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
	u32 ctrl, ctrl_ext, rctl, status;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
	/* Runtime suspend should only enable wakeup for link changes */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
	int retval = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
	netif_device_detach(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
	if (netif_running(netdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
		e1000e_down(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
		e1000_free_irq(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	e1000e_reset_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
	retval = pci_save_state(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
	if (retval)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
		return retval;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
	status = er32(STATUS);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
	if (status & E1000_STATUS_LU)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
		wufc &= ~E1000_WUFC_LNKC;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
	if (wufc) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
		e1000_setup_rctl(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
		e1000_set_multi(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
		/* turn on all-multi mode if wake on multicast is enabled */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
		if (wufc & E1000_WUFC_MC) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
			rctl = er32(RCTL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
			rctl |= E1000_RCTL_MPE;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
			ew32(RCTL, rctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
		ctrl = er32(CTRL);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
		/* advertise wake from D3Cold */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
		#define E1000_CTRL_ADVD3WUC 0x00100000
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
		/* phy power management enable */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
		#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
		ctrl |= E1000_CTRL_ADVD3WUC;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
		ew32(CTRL, ctrl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
		    adapter->hw.phy.media_type ==
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
		    e1000_media_type_internal_serdes) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
			/* keep the laser running in D3 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
			ctrl_ext = er32(CTRL_EXT);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
			ew32(CTRL_EXT, ctrl_ext);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
		if (adapter->flags & FLAG_IS_ICH)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
			e1000e_disable_gig_wol_ich8lan(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
		/* Allow time for pending master requests to run */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
		e1000e_disable_pcie_master(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
			/* enable wakeup by the PHY */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
			retval = e1000_init_phy_wakeup(adapter, wufc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
			if (retval)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
				return retval;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
		} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
			/* enable wakeup by the MAC */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
			ew32(WUFC, wufc);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
			ew32(WUC, E1000_WUC_PME_EN);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
		ew32(WUC, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
		ew32(WUFC, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
	*enable_wake = !!wufc;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
	/* make sure adapter isn't asleep if manageability is enabled */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
	if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
	    (hw->mac.ops.check_mng_mode(hw)))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
		*enable_wake = true;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
	if (adapter->hw.phy.type == e1000_phy_igp_3)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
	 * would have already happened in close and is redundant.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
	e1000_release_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
	pci_disable_device(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	if (sleep && wake) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		pci_prepare_to_sleep(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
	pci_wake_from_d3(pdev, wake);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	pci_set_power_state(pdev, PCI_D3hot);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
                                    bool wake)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
	 * The pci-e switch on some quad port adapters will report a
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
	 * correctable error when the MAC transitions from D0 to D3.  To
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
	 * prevent this we need to mask off the correctable errors on the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
	 * downstream port of the pci-e switch.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
		struct pci_dev *us_dev = pdev->bus->self;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
		int pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
		u16 devctl;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
		pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
		                      (devctl & ~PCI_EXP_DEVCTL_CERE));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
		e1000_power_off(pdev, sleep, wake);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
		e1000_power_off(pdev, sleep, wake);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
#ifdef CONFIG_PCIEASPM
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
	pci_disable_link_state(pdev, state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
#else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	int pos;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
	u16 reg16;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
	 * Both device and parent should have the same ASPM setting.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
	 * Disable ASPM in downstream component first and then upstream.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
	pos = pci_pcie_cap(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	reg16 &= ~state;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
	if (!pdev->bus->self)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	pos = pci_pcie_cap(pdev->bus->self);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	reg16 &= ~state;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
	pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
#endif
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
	dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
		 (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
		 (state & PCIE_LINK_STATE_L1) ? "L1" : "");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
	__e1000e_disable_aspm(pdev, state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
#ifdef CONFIG_PM_OPS
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
static bool e1000e_pm_ready(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
	return !!adapter->tx_ring->buffer_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
static int __e1000_resume(struct pci_dev *pdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
	u32 err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	pci_set_power_state(pdev, PCI_D0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
	pci_restore_state(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
	pci_save_state(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
	e1000e_set_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
	if (netif_running(netdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
		err = e1000_request_irq(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
		if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
			return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
	e1000e_power_up_phy(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
	/* report the system wakeup cause from S3/S4 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
		u16 phy_data;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
		e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
		if (phy_data) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
			e_info("PHY Wakeup cause - %s\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
				phy_data & E1000_WUS_EX ? "Unicast Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
				phy_data & E1000_WUS_MC ? "Multicast Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
				phy_data & E1000_WUS_BC ? "Broadcast Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
				phy_data & E1000_WUS_MAG ? "Magic Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
				phy_data & E1000_WUS_LNKC ? "Link Status "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
				" Change" : "other");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
		u32 wus = er32(WUS);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
		if (wus) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
			e_info("MAC Wakeup cause - %s\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
				wus & E1000_WUS_EX ? "Unicast Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
				wus & E1000_WUS_MC ? "Multicast Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
				wus & E1000_WUS_BC ? "Broadcast Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
				wus & E1000_WUS_MAG ? "Magic Packet" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
				wus & E1000_WUS_LNKC ? "Link Status Change" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
				"other");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
		ew32(WUS, ~0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
	e1000e_reset(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
	e1000_init_manageability_pt(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	if (netif_running(netdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
		e1000e_up(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
	netif_device_attach(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
	 * If the controller has AMT, do not set DRV_LOAD until the interface
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
	 * is up.  For all other cases, let the f/w know that the h/w is now
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
	 * under the control of the driver.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
	if (!(adapter->flags & FLAG_HAS_AMT))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
		e1000_get_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
#ifdef CONFIG_PM_SLEEP
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
static int e1000_suspend(struct device *dev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
	struct pci_dev *pdev = to_pci_dev(dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
	int retval;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
	bool wake;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
	retval = __e1000_shutdown(pdev, &wake, false);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
	if (!retval)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
		e1000_complete_shutdown(pdev, true, wake);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
	return retval;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
static int e1000_resume(struct device *dev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
	struct pci_dev *pdev = to_pci_dev(dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
	if (e1000e_pm_ready(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
		adapter->idle_check = true;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
	return __e1000_resume(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
#endif /* CONFIG_PM_SLEEP */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
#ifdef CONFIG_PM_RUNTIME
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
static int e1000_runtime_suspend(struct device *dev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
	struct pci_dev *pdev = to_pci_dev(dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
	if (e1000e_pm_ready(adapter)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
		bool wake;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
		__e1000_shutdown(pdev, &wake, true);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
static int e1000_idle(struct device *dev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	struct pci_dev *pdev = to_pci_dev(dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
	if (!e1000e_pm_ready(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
	if (adapter->idle_check) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
		adapter->idle_check = false;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
		if (!e1000e_has_link(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
			pm_schedule_suspend(dev, MSEC_PER_SEC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	return -EBUSY;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
static int e1000_runtime_resume(struct device *dev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	struct pci_dev *pdev = to_pci_dev(dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
	if (!e1000e_pm_ready(adapter))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
		return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
	adapter->idle_check = !dev->power.runtime_auto;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
	return __e1000_resume(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
#endif /* CONFIG_PM_RUNTIME */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
#endif /* CONFIG_PM_OPS */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
static void e1000_shutdown(struct pci_dev *pdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
	bool wake = false;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
	__e1000_shutdown(pdev, &wake, false);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
	if (system_state == SYSTEM_POWER_OFF)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
		e1000_complete_shutdown(pdev, false, wake);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
#ifdef CONFIG_NET_POLL_CONTROLLER
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
 * Polling 'interrupt' - used by things like netconsole to send skbs
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
 * without having to re-enable interrupts. It's not called while
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
 * the interrupt routine is executing.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
static void e1000_netpoll(struct net_device *netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
	disable_irq(adapter->pdev->irq);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
	e1000_intr(adapter->pdev->irq, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
	enable_irq(adapter->pdev->irq);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
#endif
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
 * e1000_io_error_detected - called when PCI error is detected
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
 * @pdev: Pointer to PCI device
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
 * @state: The current pci connection state
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
 * This function is called after a PCI bus error affecting
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
 * this device has been detected.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
						pci_channel_state_t state)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
	netif_device_detach(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
	if (state == pci_channel_io_perm_failure)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
		return PCI_ERS_RESULT_DISCONNECT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
	if (netif_running(netdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
		e1000e_down(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	pci_disable_device(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
	/* Request a slot slot reset. */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
	return PCI_ERS_RESULT_NEED_RESET;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
 * e1000_io_slot_reset - called after the pci bus has been reset.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
 * @pdev: Pointer to PCI device
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
 * Restart the card from scratch, as if from a cold-boot. Implementation
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
 * resembles the first-half of the e1000_resume routine.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	int err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
	pci_ers_result_t result;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
	err = pci_enable_device_mem(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
	if (err) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
		dev_err(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
			"Cannot re-enable PCI device after reset.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
		result = PCI_ERS_RESULT_DISCONNECT;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
		pci_set_master(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
		pdev->state_saved = true;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
		pci_restore_state(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
		pci_enable_wake(pdev, PCI_D3hot, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
		pci_enable_wake(pdev, PCI_D3cold, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
		e1000e_reset(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
		ew32(WUS, ~0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
		result = PCI_ERS_RESULT_RECOVERED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
	pci_cleanup_aer_uncorrect_error_status(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
	return result;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
 * e1000_io_resume - called when traffic can start flowing again.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
 * @pdev: Pointer to PCI device
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
 * This callback is called when the error recovery driver tells us that
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
 * its OK to resume normal operation. Implementation resembles the
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
 * second-half of the e1000_resume routine.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
static void e1000_io_resume(struct pci_dev *pdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
	e1000_init_manageability_pt(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
	if (netif_running(netdev)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
		if (e1000e_up(adapter)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
			dev_err(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
				"can't bring device back up after reset\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
			return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
	netif_device_attach(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
	 * If the controller has AMT, do not set DRV_LOAD until the interface
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
	 * is up.  For all other cases, let the f/w know that the h/w is now
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
	 * under the control of the driver.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
	if (!(adapter->flags & FLAG_HAS_AMT))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
		e1000_get_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
static void e1000_print_device_info(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
	struct net_device *netdev = adapter->netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
	u32 pba_num;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
	/* print bus type/speed/width info */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
	e_info("(PCI Express:2.5GB/s:%s) %pM\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
	       /* bus width */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
	        "Width x1"),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
	       /* MAC address */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
	       netdev->dev_addr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
	e_info("Intel(R) PRO/%s Network Connection\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
	e1000e_read_pba_num(hw, &pba_num);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
	e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
	       hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
	struct e1000_hw *hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
	int ret_val;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
	u16 buf = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
	if (hw->mac.type != e1000_82573)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
		return;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
	if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
		/* Deep Smart Power Down (DSPD) */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
		dev_warn(&adapter->pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
			 "Warning: detected DSPD enabled in EEPROM\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
static const struct net_device_ops e1000e_netdev_ops = {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
	.ndo_open		= e1000_open,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
	.ndo_stop		= e1000_close,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
	.ndo_start_xmit		= e1000_xmit_frame,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
	.ndo_get_stats		= e1000_get_stats,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
	.ndo_set_multicast_list	= e1000_set_multi,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
	.ndo_set_mac_address	= e1000_set_mac,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	.ndo_change_mtu		= e1000_change_mtu,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	.ndo_do_ioctl		= e1000_ioctl,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	.ndo_tx_timeout		= e1000_tx_timeout,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
	.ndo_validate_addr	= eth_validate_addr,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
#ifdef CONFIG_NET_POLL_CONTROLLER
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
	.ndo_poll_controller	= e1000_netpoll,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
#endif
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
 * e1000_probe - Device Initialization Routine
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
 * @pdev: PCI device information struct
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
 * @ent: entry in e1000_pci_tbl
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
 * Returns 0 on success, negative on failure
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
 * e1000_probe initializes an adapter identified by a pci_dev structure.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
 * The OS initialization, configuring of the adapter private structure,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
 * and a hardware reset occur.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
static int __devinit e1000_probe(struct pci_dev *pdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
				 const struct pci_device_id *ent)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
	struct net_device *netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
	struct e1000_adapter *adapter;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
	struct e1000_hw *hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
	resource_size_t mmio_start, mmio_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
	resource_size_t flash_start, flash_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
	static int cards_found;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
	int i, err, pci_using_dac;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
	u16 eeprom_data = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
	err = pci_enable_device_mem(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
		return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
	pci_using_dac = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
	err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
	if (!err) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
		if (!err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
			pci_using_dac = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
	} else {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
		if (err) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
			err = dma_set_coherent_mask(&pdev->dev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
						    DMA_BIT_MASK(32));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
			if (err) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
				dev_err(&pdev->dev, "No usable DMA "
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
					"configuration, aborting\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
				goto err_dma;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
			}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
	err = pci_request_selected_regions_exclusive(pdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
	                                  pci_select_bars(pdev, IORESOURCE_MEM),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
	                                  e1000e_driver_name);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
		goto err_pci_reg;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
	/* AER (Advanced Error Reporting) hooks */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
	pci_enable_pcie_error_reporting(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
	pci_set_master(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
	/* PCI config space info */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
	err = pci_save_state(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
		goto err_alloc_etherdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
	err = -ENOMEM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
	if (!netdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
		goto err_alloc_etherdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
	SET_NETDEV_DEV(netdev, &pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
	netdev->irq = pdev->irq;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
	pci_set_drvdata(pdev, netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
	adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
	hw = &adapter->hw;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
	adapter->netdev = netdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
	adapter->pdev = pdev;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
	adapter->ei = ei;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
	adapter->pba = ei->pba;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
	adapter->flags = ei->flags;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
	adapter->flags2 = ei->flags2;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
	adapter->hw.adapter = adapter;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
	adapter->hw.mac.type = ei->mac;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
	adapter->max_hw_frame_size = ei->max_hw_frame_size;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
	adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
	mmio_start = pci_resource_start(pdev, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
	mmio_len = pci_resource_len(pdev, 0);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
	err = -EIO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
	if (!adapter->hw.hw_addr)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
		goto err_ioremap;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
	if ((adapter->flags & FLAG_HAS_FLASH) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
		flash_start = pci_resource_start(pdev, 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
		flash_len = pci_resource_len(pdev, 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
		if (!adapter->hw.flash_address)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
			goto err_flashmap;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
	/* construct the net_device struct */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
	netdev->netdev_ops		= &e1000e_netdev_ops;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
	e1000e_set_ethtool_ops(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
	netdev->watchdog_timeo		= 5 * HZ;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
	netdev->mem_start = mmio_start;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
	netdev->mem_end = mmio_start + mmio_len;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
	adapter->bd_number = cards_found++;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
	e1000e_check_options(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
	/* setup adapter struct */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
	err = e1000_sw_init(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
		goto err_sw_init;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
	memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
	err = ei->get_variants(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
		goto err_hw_init;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
	if ((adapter->flags & FLAG_IS_ICH) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
	    (adapter->flags & FLAG_READ_ONLY_NVM))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
	hw->mac.ops.get_bus_info(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
	adapter->hw.phy.autoneg_wait_to_complete = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
	/* Copper options */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
		adapter->hw.phy.disable_polarity_correction = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
	if (e1000_check_reset_block(&adapter->hw))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
		e_info("PHY reset is blocked due to SOL/IDER session.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
	netdev->features = NETIF_F_SG |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
			   NETIF_F_HW_CSUM |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
			   NETIF_F_HW_VLAN_TX |
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
			   NETIF_F_HW_VLAN_RX;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
		netdev->features |= NETIF_F_HW_VLAN_FILTER;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
	netdev->features |= NETIF_F_TSO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
	netdev->features |= NETIF_F_TSO6;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
	netdev->vlan_features |= NETIF_F_TSO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
	netdev->vlan_features |= NETIF_F_TSO6;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
	netdev->vlan_features |= NETIF_F_HW_CSUM;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
	netdev->vlan_features |= NETIF_F_SG;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
	if (pci_using_dac) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
		netdev->features |= NETIF_F_HIGHDMA;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
		netdev->vlan_features |= NETIF_F_HIGHDMA;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
	if (e1000e_enable_mng_pass_thru(&adapter->hw))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
		adapter->flags |= FLAG_MNG_PT_ENABLED;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5821
	 * before reading the NVM, reset the controller to
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5822
	 * put the device in a known good starting state
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5823
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5824
	adapter->hw.mac.ops.reset_hw(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5825
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5826
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5827
	 * systems with ASPM and others may see the checksum fail on the first
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5828
	 * attempt. Let's give it a few tries
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5829
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5830
	for (i = 0;; i++) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5831
		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5832
			break;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5833
		if (i == 2) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5834
			e_err("The NVM Checksum Is Not Valid\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5835
			err = -EIO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5836
			goto err_eeprom;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5837
		}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5838
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5839
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5840
	e1000_eeprom_checks(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5841
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5842
	/* copy the MAC address */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5843
	if (e1000e_read_mac_addr(&adapter->hw))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5844
		e_err("NVM Read Error while reading MAC address\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5845
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5846
	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5847
	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5848
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5849
	if (!is_valid_ether_addr(netdev->perm_addr)) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5850
		e_err("Invalid MAC Address: %pM\n", netdev->perm_addr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5851
		err = -EIO;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5852
		goto err_eeprom;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5853
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5854
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5855
	init_timer(&adapter->watchdog_timer);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5856
	adapter->watchdog_timer.function = e1000_watchdog;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5857
	adapter->watchdog_timer.data = (unsigned long) adapter;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5858
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5859
	init_timer(&adapter->phy_info_timer);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5860
	adapter->phy_info_timer.function = e1000_update_phy_info;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5861
	adapter->phy_info_timer.data = (unsigned long) adapter;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5862
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5863
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5864
	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5865
	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5866
	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5867
	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5868
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5869
	/* Initialize link parameters. User can change them with ethtool */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5870
	adapter->hw.mac.autoneg = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5871
	adapter->fc_autoneg = 1;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5872
	adapter->hw.fc.requested_mode = e1000_fc_default;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5873
	adapter->hw.fc.current_mode = e1000_fc_default;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5874
	adapter->hw.phy.autoneg_advertised = 0x2f;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5875
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5876
	/* ring size defaults */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5877
	adapter->rx_ring->count = 256;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5878
	adapter->tx_ring->count = 256;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5879
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5880
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5881
	 * Initial Wake on LAN setting - If APM wake is enabled in
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5882
	 * the EEPROM, enable the ACPI Magic Packet filter
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5883
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5884
	if (adapter->flags & FLAG_APME_IN_WUC) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5885
		/* APME bit in EEPROM is mapped to WUC.APME */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5886
		eeprom_data = er32(WUC);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5887
		eeprom_apme_mask = E1000_WUC_APME;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5888
		if ((hw->mac.type > e1000_ich10lan) &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5889
		    (eeprom_data & E1000_WUC_PHY_WAKE))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5890
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5891
	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5892
		if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5893
		    (adapter->hw.bus.func == 1))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5894
			e1000_read_nvm(&adapter->hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5895
				NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5896
		else
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5897
			e1000_read_nvm(&adapter->hw,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5898
				NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5899
	}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5900
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5901
	/* fetch WoL from EEPROM */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5902
	if (eeprom_data & eeprom_apme_mask)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5903
		adapter->eeprom_wol |= E1000_WUFC_MAG;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5904
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5905
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5906
	 * now that we have the eeprom settings, apply the special cases
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5907
	 * where the eeprom may be wrong or the board simply won't support
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5908
	 * wake on lan on a particular port
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5909
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5910
	if (!(adapter->flags & FLAG_HAS_WOL))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5911
		adapter->eeprom_wol = 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5912
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5913
	/* initialize the wol settings based on the eeprom settings */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5914
	adapter->wol = adapter->eeprom_wol;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5915
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5916
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5917
	/* save off EEPROM version number */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5918
	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5919
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5920
	/* reset the hardware with the new settings */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5921
	e1000e_reset(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5922
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5923
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5924
	 * If the controller has AMT, do not set DRV_LOAD until the interface
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5925
	 * is up.  For all other cases, let the f/w know that the h/w is now
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5926
	 * under the control of the driver.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5927
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5928
	if (!(adapter->flags & FLAG_HAS_AMT))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5929
		e1000_get_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5930
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5931
	strcpy(netdev->name, "eth%d");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5932
	err = register_netdev(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5933
	if (err)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5934
		goto err_register;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5935
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5936
	/* carrier off reporting is important to ethtool even BEFORE open */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5937
	netif_carrier_off(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5938
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5939
	e1000_print_device_info(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5940
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5941
	if (pci_dev_run_wake(pdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5942
		pm_runtime_put_noidle(&pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5943
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5944
	return 0;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5945
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5946
err_register:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5947
	if (!(adapter->flags & FLAG_HAS_AMT))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5948
		e1000_release_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5949
err_eeprom:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5950
	if (!e1000_check_reset_block(&adapter->hw))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5951
		e1000_phy_hw_reset(&adapter->hw);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5952
err_hw_init:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5953
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5954
	kfree(adapter->tx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5955
	kfree(adapter->rx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5956
err_sw_init:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5957
	if (adapter->hw.flash_address)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5958
		iounmap(adapter->hw.flash_address);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5959
	e1000e_reset_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5960
err_flashmap:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5961
	iounmap(adapter->hw.hw_addr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5962
err_ioremap:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5963
	free_netdev(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5964
err_alloc_etherdev:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5965
	pci_release_selected_regions(pdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5966
	                             pci_select_bars(pdev, IORESOURCE_MEM));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5967
err_pci_reg:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5968
err_dma:
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5969
	pci_disable_device(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5970
	return err;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5971
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5972
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5973
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5974
 * e1000_remove - Device Removal Routine
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5975
 * @pdev: PCI device information struct
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5976
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5977
 * e1000_remove is called by the PCI subsystem to alert the driver
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5978
 * that it should release a PCI device.  The could be caused by a
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5979
 * Hot-Plug event, or because the driver is going to be removed from
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5980
 * memory.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5981
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5982
static void __devexit e1000_remove(struct pci_dev *pdev)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5983
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5984
	struct net_device *netdev = pci_get_drvdata(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5985
	struct e1000_adapter *adapter = netdev_priv(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5986
	bool down = test_bit(__E1000_DOWN, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5987
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5988
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5989
	 * flush_scheduled work may reschedule our watchdog task, so
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5990
	 * explicitly disable watchdog tasks from being rescheduled
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5991
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5992
	if (!down)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5993
		set_bit(__E1000_DOWN, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5994
	del_timer_sync(&adapter->watchdog_timer);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5995
	del_timer_sync(&adapter->phy_info_timer);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5996
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5997
	cancel_work_sync(&adapter->reset_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5998
	cancel_work_sync(&adapter->watchdog_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5999
	cancel_work_sync(&adapter->downshift_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6000
	cancel_work_sync(&adapter->update_phy_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6001
	cancel_work_sync(&adapter->print_hang_task);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6002
	flush_scheduled_work();
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6003
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6004
	if (!(netdev->flags & IFF_UP))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6005
		e1000_power_down_phy(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6006
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6007
	/* Don't lie to e1000_close() down the road. */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6008
	if (!down)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6009
		clear_bit(__E1000_DOWN, &adapter->state);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6010
	unregister_netdev(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6011
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6012
	if (pci_dev_run_wake(pdev))
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6013
		pm_runtime_get_noresume(&pdev->dev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6014
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6015
	/*
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6016
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6017
	 * would have already happened in close and is redundant.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6018
	 */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6019
	e1000_release_hw_control(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6020
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6021
	e1000e_reset_interrupt_capability(adapter);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6022
	kfree(adapter->tx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6023
	kfree(adapter->rx_ring);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6024
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6025
	iounmap(adapter->hw.hw_addr);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6026
	if (adapter->hw.flash_address)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6027
		iounmap(adapter->hw.flash_address);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6028
	pci_release_selected_regions(pdev,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6029
	                             pci_select_bars(pdev, IORESOURCE_MEM));
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6030
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6031
	free_netdev(netdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6032
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6033
	/* AER disable */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6034
	pci_disable_pcie_error_reporting(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6035
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6036
	pci_disable_device(pdev);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6037
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6038
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6039
/* PCI Error Recovery (ERS) */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6040
static struct pci_error_handlers e1000_err_handler = {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6041
	.error_detected = e1000_io_error_detected,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6042
	.slot_reset = e1000_io_slot_reset,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6043
	.resume = e1000_io_resume,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6044
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6045
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6046
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6047
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6048
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6049
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6050
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6051
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6052
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6053
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6054
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6055
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6056
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6057
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6058
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6059
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6060
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6061
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6062
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6063
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6064
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6065
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6066
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6067
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6068
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6069
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6070
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6071
	  board_80003es2lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6072
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6073
	  board_80003es2lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6074
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6075
	  board_80003es2lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6076
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6077
	  board_80003es2lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6078
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6079
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6080
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6081
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6082
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6083
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6084
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6085
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6086
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6087
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6088
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6089
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6090
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6091
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6092
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6093
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6094
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6095
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6096
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6097
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6098
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6099
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6100
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6101
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6102
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6103
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6104
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_V), board_ich10lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6105
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6106
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6107
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6108
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6109
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6110
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6111
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_LM), board_pch2lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6112
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH2_LV_V), board_pch2lan },
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6113
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6114
	{ }	/* terminate list */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6115
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6116
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6117
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6118
#ifdef CONFIG_PM_OPS
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6119
static const struct dev_pm_ops e1000_pm_ops = {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6120
	SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6121
	SET_RUNTIME_PM_OPS(e1000_runtime_suspend,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6122
				e1000_runtime_resume, e1000_idle)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6123
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6124
#endif
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6125
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6126
/* PCI Device API Driver */
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6127
static struct pci_driver e1000_driver = {
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6128
	.name     = e1000e_driver_name,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6129
	.id_table = e1000_pci_tbl,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6130
	.probe    = e1000_probe,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6131
	.remove   = __devexit_p(e1000_remove),
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6132
#ifdef CONFIG_PM_OPS
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6133
	.driver.pm = &e1000_pm_ops,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6134
#endif
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6135
	.shutdown = e1000_shutdown,
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6136
	.err_handler = &e1000_err_handler
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6137
};
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6138
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6139
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6140
 * e1000_init_module - Driver Registration Routine
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6141
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6142
 * e1000_init_module is the first routine called when the driver is
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6143
 * loaded. All it does is register with the PCI subsystem.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6144
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6145
static int __init e1000_init_module(void)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6146
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6147
	int ret;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6148
	pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6149
		e1000e_driver_version);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6150
	pr_info("Copyright (c) 1999 - 2010 Intel Corporation.\n");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6151
	ret = pci_register_driver(&e1000_driver);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6152
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6153
	return ret;
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6154
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6155
module_init(e1000_init_module);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6156
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6157
/**
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6158
 * e1000_exit_module - Driver Exit Cleanup Routine
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6159
 *
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6160
 * e1000_exit_module is called just before the driver is removed
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6161
 * from memory.
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6162
 **/
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6163
static void __exit e1000_exit_module(void)
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6164
{
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6165
	pci_unregister_driver(&e1000_driver);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6166
}
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6167
module_exit(e1000_exit_module);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6168
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6169
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6170
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6171
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6172
MODULE_LICENSE("GPL");
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6173
MODULE_VERSION(DRV_VERSION);
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6174
941f2d72f115 Added e1000e driver for 2.6.37.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6175
/* e1000_main.c */