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

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2009 Intel Corporation.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
    27
  vim: noexpandtab
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
    28
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
*******************************************************************************/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/module.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/types.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/init.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/pci.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/vmalloc.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/pagemap.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <linux/delay.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <linux/netdevice.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <linux/tcp.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <linux/ipv6.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <linux/slab.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <net/checksum.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <net/ip6_checksum.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
#include <linux/mii.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include <linux/ethtool.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
#include <linux/if_vlan.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#include <linux/cpu.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
#include <linux/smp.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#include <linux/pm_qos_params.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
#include <linux/pm_runtime.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
#include <linux/aer.h>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
#include "e1000-2.6.35-ethercat.h"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
#define DRV_VERSION "1.0.2-k4 (EtherCAT)"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
char e1000e_driver_name[] = "ec_e1000e";
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
const char e1000e_driver_version[] = DRV_VERSION;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
static const struct e1000_info *e1000_info_tbl[] = {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	[board_82571]		= &e1000_82571_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	[board_82572]		= &e1000_82572_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	[board_82573]		= &e1000_82573_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	[board_82574]		= &e1000_82574_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	[board_82583]		= &e1000_82583_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	[board_80003es2lan]	= &e1000_es2_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	[board_ich8lan]		= &e1000_ich8_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	[board_ich9lan]		= &e1000_ich9_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	[board_ich10lan]	= &e1000_ich10_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	[board_pchlan]		= &e1000_pch_info,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
struct e1000_reg_info {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	u32 ofs;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	char *name;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
#define E1000_RDFH	0x02410 /* Rx Data FIFO Head - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
#define E1000_RDFT	0x02418 /* Rx Data FIFO Tail - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
#define E1000_RDFHS	0x02420 /* Rx Data FIFO Head Saved - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
#define E1000_RDFTS	0x02428 /* Rx Data FIFO Tail Saved - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
#define E1000_RDFPC	0x02430 /* Rx Data FIFO Packet Count - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
#define E1000_TDFH	0x03410 /* Tx Data FIFO Head - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
#define E1000_TDFT	0x03418 /* Tx Data FIFO Tail - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
#define E1000_TDFHS	0x03420 /* Tx Data FIFO Head Saved - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
#define E1000_TDFTS	0x03428 /* Tx Data FIFO Tail Saved - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
#define E1000_TDFPC	0x03430 /* Tx Data FIFO Packet Count - RW */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
static const struct e1000_reg_info e1000_reg_info_tbl[] = {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	/* General Registers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	{E1000_CTRL, "CTRL"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	{E1000_STATUS, "STATUS"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	{E1000_CTRL_EXT, "CTRL_EXT"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	/* Interrupt Registers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	{E1000_ICR, "ICR"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	/* RX Registers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	{E1000_RCTL, "RCTL"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	{E1000_RDLEN, "RDLEN"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	{E1000_RDH, "RDH"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	{E1000_RDT, "RDT"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	{E1000_RDTR, "RDTR"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	{E1000_RXDCTL(0), "RXDCTL"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	{E1000_ERT, "ERT"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	{E1000_RDBAL, "RDBAL"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	{E1000_RDBAH, "RDBAH"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	{E1000_RDFH, "RDFH"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	{E1000_RDFT, "RDFT"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	{E1000_RDFHS, "RDFHS"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	{E1000_RDFTS, "RDFTS"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	{E1000_RDFPC, "RDFPC"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	/* TX Registers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	{E1000_TCTL, "TCTL"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	{E1000_TDBAL, "TDBAL"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	{E1000_TDBAH, "TDBAH"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	{E1000_TDLEN, "TDLEN"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	{E1000_TDH, "TDH"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
	{E1000_TDT, "TDT"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	{E1000_TIDV, "TIDV"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	{E1000_TXDCTL(0), "TXDCTL"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	{E1000_TADV, "TADV"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	{E1000_TARC(0), "TARC"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
	{E1000_TDFH, "TDFH"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	{E1000_TDFT, "TDFT"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	{E1000_TDFHS, "TDFHS"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	{E1000_TDFTS, "TDFTS"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	{E1000_TDFPC, "TDFPC"},
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
	/* List Terminator */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
	{}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
 * e1000_regdump - register printout routine
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	int n = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
	char rname[16];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
	u32 regs[8];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
	switch (reginfo->ofs) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
	case E1000_RXDCTL(0):
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
		for (n = 0; n < 2; n++)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
			regs[n] = __er32(hw, E1000_RXDCTL(n));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
	case E1000_TXDCTL(0):
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
		for (n = 0; n < 2; n++)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
			regs[n] = __er32(hw, E1000_TXDCTL(n));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
	case E1000_TARC(0):
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
		for (n = 0; n < 2; n++)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
			regs[n] = __er32(hw, E1000_TARC(n));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
		printk(KERN_INFO "%-15s %08x\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
			reginfo->name, __er32(hw, reginfo->ofs));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
	snprintf(rname, 16, "%s%s", reginfo->name, "[0-1]");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
	printk(KERN_INFO "%-15s ", rname);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
	for (n = 0; n < 2; n++)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		printk(KERN_CONT "%08x ", regs[n]);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	printk(KERN_CONT "\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
 * e1000e_dump - Print registers, tx-ring and rx-ring
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
static void e1000e_dump(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
	struct e1000_reg_info *reginfo;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
	struct e1000_tx_desc *tx_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
	struct my_u0 { u64 a; u64 b; } *u0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	union e1000_rx_desc_packet_split *rx_desc_ps;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
	struct e1000_rx_desc *rx_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
	struct my_u1 { u64 a; u64 b; u64 c; u64 d; } *u1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
	u32 staterr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	int i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	if (!netif_msg_hw(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	/* Print netdevice Info */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	if (netdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
		dev_info(&adapter->pdev->dev, "Net device Info\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		printk(KERN_INFO "Device Name     state            "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
			"trans_start      last_rx\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		printk(KERN_INFO "%-15s %016lX %016lX %016lX\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
			netdev->name,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
			netdev->state,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
			netdev->trans_start,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
			netdev->last_rx);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	/* Print Registers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	dev_info(&adapter->pdev->dev, "Register Dump\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
	printk(KERN_INFO " Register Name   Value\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	for (reginfo = (struct e1000_reg_info *)e1000_reg_info_tbl;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
	     reginfo->name; reginfo++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
		e1000_regdump(hw, reginfo);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	/* Print TX Ring Summary */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
	if (!netdev || !netif_running(netdev))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
		goto exit;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	dev_info(&adapter->pdev->dev, "TX Rings Summary\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma  ]"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
		" leng ntw timestamp\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	buffer_info = &tx_ring->buffer_info[tx_ring->next_to_clean];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
		0, tx_ring->next_to_use, tx_ring->next_to_clean,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
		(u64)buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
		buffer_info->length,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
		buffer_info->next_to_watch,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
		(u64)buffer_info->time_stamp);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	/* Print TX Rings */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	if (!netif_msg_tx_done(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
		goto rx_ring_summary;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
	dev_info(&adapter->pdev->dev, "TX Rings Dump\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	/* Transmit Descriptor Formats - DEXT[29] is 0 (Legacy) or 1 (Extended)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
	 * Legacy Transmit Descriptor
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	 *   +--------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	 * 0 |         Buffer Address [63:0] (Reserved on Write Back)       |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
	 *   +--------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	 * 8 | Special  |    CSS     | Status |  CMD    |  CSO   |  Length  |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
	 *   +--------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	 *   63       48 47        36 35    32 31     24 23    16 15        0
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	 * Extended Context Descriptor (DTYP=0x0) for TSO or checksum offload
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	 *   63      48 47    40 39       32 31             16 15    8 7      0
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	 *   +----------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	 * 0 |  TUCSE  | TUCS0  |   TUCSS   |     IPCSE       | IPCS0 | IPCSS |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	 *   +----------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	 * 8 |   MSS   | HDRLEN | RSV | STA | TUCMD | DTYP |      PAYLEN      |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	 *   +----------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
	 *   63      48 47    40 39 36 35 32 31   24 23  20 19                0
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
	 * Extended Data Descriptor (DTYP=0x1)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
	 *   +----------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	 * 0 |                     Buffer Address [63:0]                      |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	 *   +----------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
	 * 8 | VLAN tag |  POPTS  | Rsvd | Status | Command | DTYP |  DTALEN  |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
	 *   +----------------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
	 *   63       48 47     40 39  36 35    32 31     24 23  20 19        0
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
	printk(KERN_INFO "Tl[desc]     [address 63:0  ] [SpeCssSCmCsLen]"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
		" [bi->dma       ] leng  ntw timestamp        bi->skb "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
		"<-- Legacy format\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	printk(KERN_INFO "Tc[desc]     [Ce CoCsIpceCoS] [MssHlRSCm0Plen]"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
		" [bi->dma       ] leng  ntw timestamp        bi->skb "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		"<-- Ext Context format\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	printk(KERN_INFO "Td[desc]     [address 63:0  ] [VlaPoRSCm1Dlen]"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
		" [bi->dma       ] leng  ntw timestamp        bi->skb "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		"<-- Ext Data format\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
		tx_desc = E1000_TX_DESC(*tx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		u0 = (struct my_u0 *)tx_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		printk(KERN_INFO "T%c[0x%03X]    %016llX %016llX %016llX "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
			"%04X  %3X %016llX %p",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		       (!(le64_to_cpu(u0->b) & (1<<29)) ? 'l' :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
			((le64_to_cpu(u0->b) & (1<<20)) ? 'd' : 'c')), i,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
		       le64_to_cpu(u0->a), le64_to_cpu(u0->b),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
		       (u64)buffer_info->dma, buffer_info->length,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		       buffer_info->next_to_watch, (u64)buffer_info->time_stamp,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
		       buffer_info->skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
		if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
			printk(KERN_CONT " NTC/U\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
		else if (i == tx_ring->next_to_use)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
			printk(KERN_CONT " NTU\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		else if (i == tx_ring->next_to_clean)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
			printk(KERN_CONT " NTC\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
		else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
			printk(KERN_CONT "\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		if (netif_msg_pktdata(adapter) && buffer_info->dma != 0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
			print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
					16, 1, phys_to_virt(buffer_info->dma),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
					buffer_info->length, true);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	/* Print RX Rings Summary */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
rx_ring_summary:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	dev_info(&adapter->pdev->dev, "RX Rings Summary\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	printk(KERN_INFO "Queue [NTU] [NTC]\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	printk(KERN_INFO " %5d %5X %5X\n", 0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
		rx_ring->next_to_use, rx_ring->next_to_clean);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	/* Print RX Rings */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
	if (!netif_msg_rx_status(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
		goto exit;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
	dev_info(&adapter->pdev->dev, "RX Rings Dump\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
	switch (adapter->rx_ps_pages) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	case 1:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
	case 2:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
	case 3:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		/* [Extended] Packet Split Receive Descriptor Format
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
		 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
		 *    +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		 *  0 |                Buffer Address 0 [63:0]              |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
		 *    +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
		 *  8 |                Buffer Address 1 [63:0]              |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
		 *    +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
		 * 16 |                Buffer Address 2 [63:0]              |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
		 *    +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		 * 24 |                Buffer Address 3 [63:0]              |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		 *    +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
		printk(KERN_INFO "R  [desc]      [buffer 0 63:0 ] "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
			"[buffer 1 63:0 ] "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
		       "[buffer 2 63:0 ] [buffer 3 63:0 ] [bi->dma       ] "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
		       "[bi->skb] <-- Ext Pkt Split format\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
		/* [Extended] Receive Descriptor (Write-Back) Format
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
		 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
		 *   63       48 47    32 31     13 12    8 7    4 3        0
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
		 *   +------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		 * 0 | Packet   | IP     |  Rsvd   | MRQ   | Rsvd | MRQ RSS |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
		 *   | Checksum | Ident  |         | Queue |      |  Type   |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		 *   +------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
		 * 8 | VLAN Tag | Length | Extended Error | Extended Status |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
		 *   +------------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
		 *   63       48 47    32 31            20 19               0
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		printk(KERN_INFO "RWB[desc]      [ck ipid mrqhsh] "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
			"[vl   l0 ee  es] "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		       "[ l3  l2  l1 hs] [reserved      ] ---------------- "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		       "[bi->skb] <-- Ext Rx Write-Back format\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		for (i = 0; i < rx_ring->count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
			buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
			rx_desc_ps = E1000_RX_DESC_PS(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
			u1 = (struct my_u1 *)rx_desc_ps;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
			staterr =
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
				le32_to_cpu(rx_desc_ps->wb.middle.status_error);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
			if (staterr & E1000_RXD_STAT_DD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
				/* Descriptor Done */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
				printk(KERN_INFO "RWB[0x%03X]     %016llX "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
					"%016llX %016llX %016llX "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
					"---------------- %p", i,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
					le64_to_cpu(u1->a),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
					le64_to_cpu(u1->b),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
					le64_to_cpu(u1->c),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
					le64_to_cpu(u1->d),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
					buffer_info->skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
			} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
				printk(KERN_INFO "R  [0x%03X]     %016llX "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
					"%016llX %016llX %016llX %016llX %p", i,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
					le64_to_cpu(u1->a),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
					le64_to_cpu(u1->b),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
					le64_to_cpu(u1->c),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
					le64_to_cpu(u1->d),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
					(u64)buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
					buffer_info->skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
				if (netif_msg_pktdata(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
					print_hex_dump(KERN_INFO, "",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
						DUMP_PREFIX_ADDRESS, 16, 1,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
						phys_to_virt(buffer_info->dma),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
						adapter->rx_ps_bsize0, true);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
			if (i == rx_ring->next_to_use)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
				printk(KERN_CONT " NTU\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
			else if (i == rx_ring->next_to_clean)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
				printk(KERN_CONT " NTC\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
				printk(KERN_CONT "\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	case 0:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		/* Legacy Receive Descriptor Format
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		 * +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		 * |                Buffer Address [63:0]                |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
		 * +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		 * | VLAN Tag | Errors | Status 0 | Packet csum | Length |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
		 * +-----------------------------------------------------+
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
		 * 63       48 47    40 39      32 31         16 15      0
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
		printk(KERN_INFO "Rl[desc]     [address 63:0  ] "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
			"[vl er S cks ln] [bi->dma       ] [bi->skb] "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
			"<-- Legacy format\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
		for (i = 0; rx_ring->desc && (i < rx_ring->count); i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
			rx_desc = E1000_RX_DESC(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
			buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
			u0 = (struct my_u0 *)rx_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
			printk(KERN_INFO "Rl[0x%03X]    %016llX %016llX "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
				"%016llX %p",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
				i, le64_to_cpu(u0->a), le64_to_cpu(u0->b),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
				(u64)buffer_info->dma, buffer_info->skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
			if (i == rx_ring->next_to_use)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
				printk(KERN_CONT " NTU\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
			else if (i == rx_ring->next_to_clean)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
				printk(KERN_CONT " NTC\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
			else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
				printk(KERN_CONT "\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
			if (netif_msg_pktdata(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
				print_hex_dump(KERN_INFO, "",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
					DUMP_PREFIX_ADDRESS,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
					16, 1, phys_to_virt(buffer_info->dma),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
					adapter->rx_buffer_len, true);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
exit:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
 * e1000_desc_unused - calculate if we have unused descriptors
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
static int e1000_desc_unused(struct e1000_ring *ring)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
	if (ring->next_to_clean > ring->next_to_use)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
		return ring->next_to_clean - ring->next_to_use - 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
 * e1000_receive_skb - helper function to handle Rx indications
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
 * @status: descriptor status field as written by hardware
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
 * @skb: pointer to sk_buff to be indicated to stack
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
static void e1000_receive_skb(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
			      struct net_device *netdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
			      struct sk_buff *skb,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
			      u8 status, __le16 vlan)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	skb->protocol = eth_type_trans(skb, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
				 le16_to_cpu(vlan), skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		napi_gro_receive(&adapter->napi, skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
 * e1000_rx_checksum - Receive Checksum Offload for 82543
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
 * @adapter:     board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
 * @status_err:  receive descriptor status and error fields
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
 * @csum:	receive descriptor csum field
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
 * @sk_buff:     socket buffer with received data
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
			      u32 csum, struct sk_buff *skb)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
	u16 status = (u16)status_err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
	u8 errors = (u8)(status_err >> 24);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
	skb->ip_summed = CHECKSUM_NONE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
	/* Ignore Checksum bit is set */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
	if (status & E1000_RXD_STAT_IXSM)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
	/* TCP/UDP checksum error bit is set */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	if (errors & E1000_RXD_ERR_TCPE) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		/* let the stack verify checksum errors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		adapter->hw_csum_err++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	/* TCP/UDP Checksum has not been calculated */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	/* It must be a TCP or UDP packet with a valid checksum */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	if (status & E1000_RXD_STAT_TCPCS) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		/* TCP checksum is good */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		skb->ip_summed = CHECKSUM_UNNECESSARY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		 * IP fragment with UDP payload
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
		 * Hardware complements the payload checksum, so we undo it
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
		 * and then put the value in host order for further stack use.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		__sum16 sum = (__force __sum16)htons(csum);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
		skb->csum = csum_unfold(~sum);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
		skb->ip_summed = CHECKSUM_COMPLETE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	adapter->hw_csum_good++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
 * @adapter: address of board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
				   int cleaned_count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	struct e1000_rx_desc *rx_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	struct sk_buff *skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	unsigned int bufsz = adapter->rx_buffer_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
	i = rx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	while (cleaned_count--) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		skb = buffer_info->skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		if (skb) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
			skb_trim(skb, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
			goto map_skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
		if (!skb) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
			/* Better luck next round */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
			adapter->alloc_rx_buff_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
		buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
map_skb:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
						  adapter->rx_buffer_len,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
						  DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
			dev_err(&pdev->dev, "RX DMA map failed\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
			adapter->rx_dma_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
		rx_desc = E1000_RX_DESC(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
			 * Force memory writes to complete before letting h/w
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
			 * know there are new descriptors to fetch.  (Only
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
			 * applicable for weak-ordered memory model archs,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
			 * such as IA-64).
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
			wmb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
			writel(i, adapter->hw.hw_addr + rx_ring->tail);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
		i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		if (i == rx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
			i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
		buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	rx_ring->next_to_use = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
 * @adapter: address of board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
				      int cleaned_count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	union e1000_rx_desc_packet_split *rx_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	struct e1000_ps_page *ps_page;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	struct sk_buff *skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	unsigned int i, j;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	i = rx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	while (cleaned_count--) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
			ps_page = &buffer_info->ps_pages[j];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
			if (j >= adapter->rx_ps_pages) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
				/* all unused desc entries get hw null ptr */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
				rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
				continue;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
			if (!ps_page->page) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
				ps_page->page = alloc_page(GFP_ATOMIC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
				if (!ps_page->page) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
					adapter->alloc_rx_buff_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
					goto no_buffers;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
				}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
				ps_page->dma = dma_map_page(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
							    ps_page->page,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
							    0, PAGE_SIZE,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
							    DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
				if (dma_mapping_error(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
						      ps_page->dma)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
					dev_err(&adapter->pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
					  "RX DMA page map failed\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
					adapter->rx_dma_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
					goto no_buffers;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
				}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
			 * Refresh the desc even if buffer_addrs
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
			 * didn't change because each write-back
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
			 * erases this info.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
			rx_desc->read.buffer_addr[j+1] =
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
			     cpu_to_le64(ps_page->dma);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		skb = netdev_alloc_skb_ip_align(netdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
						adapter->rx_ps_bsize0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
		if (!skb) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
			adapter->alloc_rx_buff_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
		buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
		buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
						  adapter->rx_ps_bsize0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
						  DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
		if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
			dev_err(&pdev->dev, "RX DMA map failed\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
			adapter->rx_dma_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
			/* cleanup skb */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
			dev_kfree_skb_any(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
			buffer_info->skb = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		if (unlikely(!(i & (E1000_RX_BUFFER_WRITE - 1)))) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
			 * Force memory writes to complete before letting h/w
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
			 * know there are new descriptors to fetch.  (Only
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
			 * applicable for weak-ordered memory model archs,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
			 * such as IA-64).
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
			wmb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
			writel(i<<1, adapter->hw.hw_addr + rx_ring->tail);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		if (i == rx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
			i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
no_buffers:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
	rx_ring->next_to_use = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
 * @adapter: address of board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
 * @cleaned_count: number of buffers to allocate this pass
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
                                         int cleaned_count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	struct e1000_rx_desc *rx_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	struct sk_buff *skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	unsigned int bufsz = 256 - 16 /* for skb_reserve */;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	i = rx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	while (cleaned_count--) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		skb = buffer_info->skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		if (skb) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
			skb_trim(skb, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
			goto check_page;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		if (unlikely(!skb)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
			/* Better luck next round */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
			adapter->alloc_rx_buff_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
		buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
check_page:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
		/* allocate a new page if necessary */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
		if (!buffer_info->page) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
			buffer_info->page = alloc_page(GFP_ATOMIC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
			if (unlikely(!buffer_info->page)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
				adapter->alloc_rx_buff_failed++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
				break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
		if (!buffer_info->dma)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
			buffer_info->dma = dma_map_page(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
			                                buffer_info->page, 0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
			                                PAGE_SIZE,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
							DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
		rx_desc = E1000_RX_DESC(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
		if (unlikely(++i == rx_ring->count))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
			i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
		buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	if (likely(rx_ring->next_to_use != i)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
		rx_ring->next_to_use = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
		if (unlikely(i-- == 0))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
			i = (rx_ring->count - 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
		/* Force memory writes to complete before letting h/w
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
		 * know there are new descriptors to fetch.  (Only
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		 * applicable for weak-ordered memory model archs,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
		 * such as IA-64). */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
		wmb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
		writel(i, adapter->hw.hw_addr + rx_ring->tail);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
 * the return value indicates whether actual cleaning was done, there
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
 * is no guarantee that everything was cleaned
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
			       int *work_done, int work_to_do)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	struct e1000_rx_desc *rx_desc, *next_rxd;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	struct e1000_buffer *buffer_info, *next_buffer;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
	u32 length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
	int cleaned_count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	bool cleaned = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
	i = rx_ring->next_to_clean;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	rx_desc = E1000_RX_DESC(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	while (rx_desc->status & E1000_RXD_STAT_DD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		struct sk_buff *skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		u8 status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		if (*work_done >= work_to_do)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		(*work_done)++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		rmb();	/* read descriptor and rx_buffer_info after status DD */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
		status = rx_desc->status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		skb = buffer_info->skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
			buffer_info->skb = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		prefetch(skb->data - NET_IP_ALIGN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
		if (i == rx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
			i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
		next_rxd = E1000_RX_DESC(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		prefetch(next_rxd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		next_buffer = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		cleaned = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		cleaned_count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
		dma_unmap_single(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
				 buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
				 adapter->rx_buffer_len,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
				 DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		buffer_info->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		length = le16_to_cpu(rx_desc->length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
		 * !EOP means multiple descriptors were used to store a single
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		 * packet, if that's the case we need to toss it.  In fact, we
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
		 * need to toss every packet with the EOP bit clear and the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
		 * next frame that _does_ have the EOP bit set, as it is by
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
		 * definition only a frame fragment
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
			adapter->flags2 |= FLAG2_IS_DISCARDING;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
			/* All receives must fit into a single buffer */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
			e_dbg("Receive packet consumed multiple buffers\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
			/* recycle */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
			buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
			if (status & E1000_RXD_STAT_EOP)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
			goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		if (!adapter->ecdev && (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
			/* recycle */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
			buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
			goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		/* adjust length to remove Ethernet CRC */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			length -= 4;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		total_rx_bytes += length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
		total_rx_packets++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
		 * code added for copybreak, this should improve
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
		 * performance for small packets with large amounts
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
		 * of reassembly being done in the stack
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
		if (!adapter->ecdev && length < copybreak) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
			struct sk_buff *new_skb =
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
			    netdev_alloc_skb_ip_align(netdev, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
			if (new_skb) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
				skb_copy_to_linear_data_offset(new_skb,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
							       -NET_IP_ALIGN,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
							       (skb->data -
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
								NET_IP_ALIGN),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
							       (length +
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
								NET_IP_ALIGN));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
				/* save the skb in buffer_info as good */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
				buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
				skb = new_skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
			/* else just continue with the old one */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		/* end copybreak code */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
		skb_put(skb, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
		/* Receive Checksum Offload */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
		e1000_rx_checksum(adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
				  (u32)(status) |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
				  ((u32)(rx_desc->errors) << 24),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
				  le16_to_cpu(rx_desc->csum), skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		if (adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
			ecdev_receive(adapter->ecdev, skb->data, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
			adapter->ec_watchdog_jiffies = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
			e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
next_desc:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		rx_desc->status = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		/* return some buffers to hardware, one at a time is too slow */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
			adapter->alloc_rx_buf(adapter, cleaned_count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
			cleaned_count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		/* use prefetched values */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		rx_desc = next_rxd;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
		buffer_info = next_buffer;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	rx_ring->next_to_clean = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	cleaned_count = e1000_desc_unused(rx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	if (cleaned_count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		adapter->alloc_rx_buf(adapter, cleaned_count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	adapter->total_rx_bytes += total_rx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	adapter->total_rx_packets += total_rx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	netdev->stats.rx_bytes += total_rx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	netdev->stats.rx_packets += total_rx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	return cleaned;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
static void e1000_put_txbuf(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
			     struct e1000_buffer *buffer_info)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	if (buffer_info->dma) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		if (buffer_info->mapped_as_page)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
			dma_unmap_page(&adapter->pdev->dev, buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
				       buffer_info->length, DMA_TO_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
		else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
			dma_unmap_single(&adapter->pdev->dev, buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
					 buffer_info->length, DMA_TO_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
		buffer_info->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
	if (buffer_info->skb) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
		dev_kfree_skb_any(buffer_info->skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
		buffer_info->skb = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
	buffer_info->time_stamp = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
static void e1000_print_hw_hang(struct work_struct *work)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	struct e1000_adapter *adapter = container_of(work,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	                                             struct e1000_adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	                                             print_hang_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	unsigned int i = tx_ring->next_to_clean;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
	u16 phy_status, phy_1000t_status, phy_ext_status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	u16 pci_status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	e1e_rphy(hw, PHY_STATUS, &phy_status);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
	e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	/* detected Hardware unit hang */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	e_err("Detected Hardware Unit Hang:\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
	      "  TDH                  <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	      "  TDT                  <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	      "  next_to_use          <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	      "  next_to_clean        <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	      "buffer_info[next_to_clean]:\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	      "  time_stamp           <%lx>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	      "  next_to_watch        <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	      "  jiffies              <%lx>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	      "  next_to_watch.status <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	      "MAC Status             <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
	      "PHY Status             <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
	      "PHY 1000BASE-T Status  <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
	      "PHY Extended Status    <%x>\n"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
	      "PCI Status             <%x>\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	      readl(adapter->hw.hw_addr + tx_ring->head),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
	      readl(adapter->hw.hw_addr + tx_ring->tail),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	      tx_ring->next_to_use,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	      tx_ring->next_to_clean,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	      tx_ring->buffer_info[eop].time_stamp,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
	      eop,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	      jiffies,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	      eop_desc->upper.fields.status,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	      er32(STATUS),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	      phy_status,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	      phy_1000t_status,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	      phy_ext_status,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	      pci_status);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
 * the return value indicates whether actual cleaning was done, there
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
 * is no guarantee that everything was cleaned
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	struct e1000_tx_desc *tx_desc, *eop_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	unsigned int i, eop;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
	unsigned int count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	i = tx_ring->next_to_clean;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	eop = tx_ring->buffer_info[i].next_to_watch;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
	       (count < tx_ring->count)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		bool cleaned = false;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
		rmb(); /* read buffer_info after eop_desc */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		for (; !cleaned; count++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
			tx_desc = E1000_TX_DESC(*tx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
			buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
			cleaned = (i == eop);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
			if (cleaned) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
				total_tx_packets += buffer_info->segs;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
				total_tx_bytes += buffer_info->bytecount;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
			e1000_put_txbuf(adapter, buffer_info);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
			tx_desc->upper.data = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
			i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
			if (i == tx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
				i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		if (i == tx_ring->next_to_use)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
		eop = tx_ring->buffer_info[i].next_to_watch;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	tx_ring->next_to_clean = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
#define TX_WAKE_THRESHOLD 32
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	if (!adapter->ecdev && count && netif_carrier_ok(netdev) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
		/* Make sure that anybody stopping the queue after this
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		 * sees the new next_to_clean.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		smp_mb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		if (netif_queue_stopped(netdev) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
			netif_wake_queue(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
			++adapter->restart_queue;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
	if (!adapter->ecdev && adapter->detect_tx_hung) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		 * Detect a transmit hang in hardware, this serializes the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
		 * check with the clearing of time_stamp and movement of i
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		adapter->detect_tx_hung = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
		if (tx_ring->buffer_info[i].time_stamp &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
			       + (adapter->tx_timeout_factor * HZ)) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
			schedule_work(&adapter->print_hang_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
			netif_stop_queue(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
	adapter->total_tx_bytes += total_tx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
	adapter->total_tx_packets += total_tx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
	netdev->stats.tx_bytes += total_tx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
	netdev->stats.tx_packets += total_tx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
	return (count < tx_ring->count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
 * the return value indicates whether actual cleaning was done, there
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
 * is no guarantee that everything was cleaned
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
				  int *work_done, int work_to_do)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
	struct e1000_buffer *buffer_info, *next_buffer;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
	struct e1000_ps_page *ps_page;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
	struct sk_buff *skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	unsigned int i, j;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
	u32 length, staterr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	int cleaned_count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	bool cleaned = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
	i = rx_ring->next_to_clean;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	while (staterr & E1000_RXD_STAT_DD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		if (*work_done >= work_to_do)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		(*work_done)++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		skb = buffer_info->skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		rmb();	/* read descriptor and rx_buffer_info after status DD */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		/* in the packet split case this is header only */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		prefetch(skb->data - NET_IP_ALIGN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		if (i == rx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
			i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		prefetch(next_rxd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		next_buffer = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		cleaned = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		cleaned_count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
		dma_unmap_single(&pdev->dev, buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
				 adapter->rx_ps_bsize0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
				 DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
		buffer_info->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
		/* see !EOP comment in other rx routine */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		if (!(staterr & E1000_RXD_STAT_EOP))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
			adapter->flags2 |= FLAG2_IS_DISCARDING;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			e_dbg("Packet Split buffers didn't pick up the full "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			      "packet\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
			if (!adapter->ecdev) dev_kfree_skb_irq(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			if (staterr & E1000_RXD_STAT_EOP)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
			goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
			if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
				dev_kfree_skb_irq(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
			goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		length = le16_to_cpu(rx_desc->wb.middle.length0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		if (!length) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
			e_dbg("Last part of the packet spanning multiple "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
			      "descriptors\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
				dev_kfree_skb_irq(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
			goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		/* Good Receive */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		skb_put(skb, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		 * this looks ugly, but it seems compiler issues make it
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
		 * more efficient than reusing j
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		 * page alloc/put takes too long and effects small packet
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
		 * throughput, so unsplit small packets and save the alloc/put
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		 * only valid in softirq (napi) context to call kmap_*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
		if (l1 && (l1 <= copybreak) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
		    ((length + l1) <= adapter->rx_ps_bsize0)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
			u8 *vaddr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
			ps_page = &buffer_info->ps_pages[0];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
			 * there is no documentation about how to call
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
			 * kmap_atomic, so we can't hold the mapping
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
			 * very long
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
			dma_sync_single_for_cpu(&pdev->dev, ps_page->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
						PAGE_SIZE, DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
			vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
			memcpy(skb_tail_pointer(skb), vaddr, l1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
			dma_sync_single_for_device(&pdev->dev, ps_page->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
						   PAGE_SIZE, DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
			/* remove the CRC */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
			if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
				l1 -= 4;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			skb_put(skb, l1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
			goto copydone;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
		} /* if */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
			if (!length)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
				break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
			ps_page = &buffer_info->ps_pages[j];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
				       DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
			ps_page->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
			skb_fill_page_desc(skb, j, ps_page->page, 0, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
			ps_page->page = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
			skb->len += length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
			skb->data_len += length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
			skb->truesize += length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		/* strip the ethernet crc, problem is we're using pages now so
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		 * this whole operation can get a little cpu intensive
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
			pskb_trim(skb, skb->len - 4);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
copydone:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		total_rx_bytes += skb->len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		total_rx_packets++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		e1000_rx_checksum(adapter, staterr, le16_to_cpu(
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
			rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		if (rx_desc->wb.upper.header_status &
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
			adapter->rx_hdr_split++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		if (adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			ecdev_receive(adapter->ecdev, skb->data, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
			adapter->ec_watchdog_jiffies = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
			e1000_receive_skb(adapter, netdev, skb,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
					  staterr, rx_desc->wb.middle.vlan);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
next_desc:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		if (!adapter->ecdev) buffer_info->skb = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		/* return some buffers to hardware, one at a time is too slow */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
			adapter->alloc_rx_buf(adapter, cleaned_count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
			cleaned_count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		/* use prefetched values */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		rx_desc = next_rxd;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		buffer_info = next_buffer;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	rx_ring->next_to_clean = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	cleaned_count = e1000_desc_unused(rx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	if (cleaned_count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		adapter->alloc_rx_buf(adapter, cleaned_count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	adapter->total_rx_bytes += total_rx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	adapter->total_rx_packets += total_rx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	netdev->stats.rx_bytes += total_rx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	netdev->stats.rx_packets += total_rx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	return cleaned;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
 * e1000_consume_page - helper function
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
                               u16 length)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	bi->page = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	skb->len += length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	skb->data_len += length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	skb->truesize += length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
 * the return value indicates whether actual cleaning was done, there
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
 * is no guarantee that everything was cleaned
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
                                     int *work_done, int work_to_do)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
	struct e1000_rx_desc *rx_desc, *next_rxd;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
	struct e1000_buffer *buffer_info, *next_buffer;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	u32 length;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
	int cleaned_count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	bool cleaned = false;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
	unsigned int total_rx_bytes=0, total_rx_packets=0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
	i = rx_ring->next_to_clean;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
	rx_desc = E1000_RX_DESC(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
	while (rx_desc->status & E1000_RXD_STAT_DD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
		struct sk_buff *skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		u8 status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		if (*work_done >= work_to_do)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		(*work_done)++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
		rmb();	/* read descriptor and rx_buffer_info after status DD */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
		status = rx_desc->status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
		skb = buffer_info->skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
		if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
			buffer_info->skb = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
		++i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
		if (i == rx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
			i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
		next_rxd = E1000_RX_DESC(*rx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
		prefetch(next_rxd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
		next_buffer = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
		cleaned = true;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
		cleaned_count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
		dma_unmap_page(&pdev->dev, buffer_info->dma, PAGE_SIZE,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
			       DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
		buffer_info->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		length = le16_to_cpu(rx_desc->length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
		/* errors is only valid for DD + EOP descriptors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
		if (!adapter->ecdev && unlikely((status & E1000_RXD_STAT_EOP) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
				/* recycle both page and skb */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
				buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
				/* an error means any chain goes out the window
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
				 * too */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
				if (rx_ring->rx_skb_top)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
					dev_kfree_skb(rx_ring->rx_skb_top);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
				rx_ring->rx_skb_top = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
				goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
#define rxtop rx_ring->rx_skb_top
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		if (!(status & E1000_RXD_STAT_EOP)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
			/* this descriptor is only the beginning (or middle) */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
			if (!rxtop) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
				/* this is the beginning of a chain */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
				rxtop = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
				                   0, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
			} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
				/* this is the middle of a chain */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
				skb_fill_page_desc(rxtop,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
				    skb_shinfo(rxtop)->nr_frags,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
				    buffer_info->page, 0, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
				/* re-use the skb, only consumed the page */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
				buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
			e1000_consume_page(buffer_info, rxtop, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
			goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
			if (rxtop) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
				/* end of the chain */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
				skb_fill_page_desc(rxtop,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
				    skb_shinfo(rxtop)->nr_frags,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
				    buffer_info->page, 0, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
				/* re-use the current skb, we only consumed the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
				 * page */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
				buffer_info->skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
				skb = rxtop;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
				rxtop = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
				e1000_consume_page(buffer_info, skb, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
			} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
				/* no chain, got EOP, this buf is the packet
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
				 * copybreak to save the put_page/alloc_page */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
				if (length <= copybreak &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
				    skb_tailroom(skb) >= length) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
					u8 *vaddr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
					vaddr = kmap_atomic(buffer_info->page,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
					                   KM_SKB_DATA_SOFTIRQ);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
					memcpy(skb_tail_pointer(skb), vaddr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
					       length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
					kunmap_atomic(vaddr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
					              KM_SKB_DATA_SOFTIRQ);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
					/* re-use the page, so don't erase
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
					 * buffer_info->page */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
					skb_put(skb, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
				} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
					skb_fill_page_desc(skb, 0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
					                   buffer_info->page, 0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
				                           length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
					e1000_consume_page(buffer_info, skb,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
					                   length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
				}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		e1000_rx_checksum(adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
		                  (u32)(status) |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		                  ((u32)(rx_desc->errors) << 24),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
		                  le16_to_cpu(rx_desc->csum), skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
		/* probably a little skewed due to removing CRC */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		total_rx_bytes += skb->len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
		total_rx_packets++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
		/* eth type trans needs skb->data to point to something */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		if (!adapter->ecdev && !pskb_may_pull(skb, ETH_HLEN)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
			e_err("pskb_may_pull failed.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
			dev_kfree_skb(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
			goto next_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		if (adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
			ecdev_receive(adapter->ecdev, skb->data, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
			adapter->ec_watchdog_jiffies = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
			e1000_receive_skb(adapter, netdev, skb, status,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
			                  rx_desc->special);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
next_desc:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		rx_desc->status = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
		/* return some buffers to hardware, one at a time is too slow */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
			adapter->alloc_rx_buf(adapter, cleaned_count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
			cleaned_count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
		/* use prefetched values */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		rx_desc = next_rxd;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		buffer_info = next_buffer;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	rx_ring->next_to_clean = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	cleaned_count = e1000_desc_unused(rx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	if (cleaned_count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
		adapter->alloc_rx_buf(adapter, cleaned_count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	adapter->total_rx_bytes += total_rx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	adapter->total_rx_packets += total_rx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	netdev->stats.rx_bytes += total_rx_bytes;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
	netdev->stats.rx_packets += total_rx_packets;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	return cleaned;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	struct e1000_ps_page *ps_page;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	unsigned int i, j;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	/* Free all the Rx ring sk_buffs */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	for (i = 0; i < rx_ring->count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		if (buffer_info->dma) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
			if (adapter->clean_rx == e1000_clean_rx_irq)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
				dma_unmap_single(&pdev->dev, buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
						 adapter->rx_buffer_len,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
						 DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
				dma_unmap_page(&pdev->dev, buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
				               PAGE_SIZE,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
					       DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
				dma_unmap_single(&pdev->dev, buffer_info->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
						 adapter->rx_ps_bsize0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
						 DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
			buffer_info->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		if (buffer_info->page) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
			put_page(buffer_info->page);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
			buffer_info->page = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
		if (buffer_info->skb) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
			dev_kfree_skb(buffer_info->skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
			buffer_info->skb = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
			ps_page = &buffer_info->ps_pages[j];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
			if (!ps_page->page)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
				break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
			dma_unmap_page(&pdev->dev, ps_page->dma, PAGE_SIZE,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
				       DMA_FROM_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
			ps_page->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
			put_page(ps_page->page);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
			ps_page->page = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	/* there also may be some cached data from a chained receive */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	if (rx_ring->rx_skb_top) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
		dev_kfree_skb(rx_ring->rx_skb_top);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
		rx_ring->rx_skb_top = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	/* Zero out the descriptor ring */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	memset(rx_ring->desc, 0, rx_ring->size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	rx_ring->next_to_clean = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
	rx_ring->next_to_use = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
	writel(0, adapter->hw.hw_addr + rx_ring->head);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	writel(0, adapter->hw.hw_addr + rx_ring->tail);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
static void e1000e_downshift_workaround(struct work_struct *work)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
	struct e1000_adapter *adapter = container_of(work,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
					struct e1000_adapter, downshift_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
 * e1000_intr_msi - Interrupt Handler
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
 * @irq: interrupt number
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
 * @data: pointer to a network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
static irqreturn_t e1000_intr_msi(int irq, void *data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
	struct net_device *netdev = data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	u32 icr = er32(ICR);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1537
	if (adapter->ecdev) {
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1538
		int ec_work_done = 0;
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1539
		adapter->clean_rx(adapter, &ec_work_done, 100);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1540
		e1000_clean_tx_irq(adapter);
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
		return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	 * read ICR disables interrupts using IAM
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	if (icr & E1000_ICR_LSC) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		hw->mac.get_link_status = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		 * ICH8 workaround-- Call gig speed drop workaround on cable
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		 * disconnect (LSC) before accessing any PHY registers
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		    (!(er32(STATUS) & E1000_STATUS_LU)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
			schedule_work(&adapter->downshift_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		 * 80003ES2LAN workaround-- For packet buffer work-around on
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		 * link down event; disable receives here in the ISR and reset
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		 * adapter in watchdog
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		if (netif_carrier_ok(netdev) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
			/* disable receives */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
			u32 rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
			adapter->flags |= FLAG_RX_RESTART_NOW;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
		/* guard against interrupt when we're going down */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	if (napi_schedule_prep(&adapter->napi)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
		adapter->total_tx_bytes = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
		adapter->total_tx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		adapter->total_rx_bytes = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
		adapter->total_rx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		__napi_schedule(&adapter->napi);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
	return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
 * e1000_intr - Interrupt Handler
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
 * @irq: interrupt number
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
 * @data: pointer to a network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
static irqreturn_t e1000_intr(int irq, void *data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
	struct net_device *netdev = data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	u32 rctl, icr = er32(ICR);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		return IRQ_NONE;  /* Not our interrupt */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	 * IMS will not auto-mask if INT_ASSERTED is not set, and if it is
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	 * not set, then the adapter didn't send an interrupt
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	if (!adapter->ecdev && !(icr & E1000_ICR_INT_ASSERTED))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		return IRQ_NONE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	 * Interrupt Auto-Mask...upon reading ICR,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	 * interrupts are masked.  No need for the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	 * IMC write
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	if (!adapter->ecdev && (icr & E1000_ICR_LSC)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
		hw->mac.get_link_status = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
		 * ICH8 workaround-- Call gig speed drop workaround on cable
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		 * disconnect (LSC) before accessing any PHY registers
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
		    (!(er32(STATUS) & E1000_STATUS_LU)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
			schedule_work(&adapter->downshift_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		 * 80003ES2LAN workaround--
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
		 * For packet buffer work-around on link down event;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		 * disable receives here in the ISR and
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		 * reset adapter in watchdog
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
		if (netif_carrier_ok(netdev) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
			/* disable receives */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
			rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
			adapter->flags |= FLAG_RX_RESTART_NOW;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		/* guard against interrupt when we're going down */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
		if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1641
	if (adapter->ecdev) {
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1642
		int ec_work_done = 0;
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1643
		adapter->clean_rx(adapter, &ec_work_done, 100);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1644
		e1000_clean_tx_irq(adapter);
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
	if (napi_schedule_prep(&adapter->napi)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		adapter->total_tx_bytes = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		adapter->total_tx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		adapter->total_rx_bytes = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		adapter->total_rx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		__napi_schedule(&adapter->napi);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
static irqreturn_t e1000_msix_other(int irq, void *data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	struct net_device *netdev = data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
	u32 icr = er32(ICR);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
			ew32(IMS, E1000_IMS_OTHER);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
		return IRQ_NONE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
	if (icr & adapter->eiac_mask)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		ew32(ICS, (icr & adapter->eiac_mask));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
	if (icr & E1000_ICR_OTHER) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		if (!(icr & E1000_ICR_LSC))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
			goto no_link_interrupt;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		hw->mac.get_link_status = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		/* guard against interrupt when we're going down */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
no_link_interrupt:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
	if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
static irqreturn_t e1000_intr_msix_tx(int irq, void *data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	struct net_device *netdev = data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	adapter->total_tx_bytes = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	adapter->total_tx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	if (!e1000_clean_tx_irq(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		/* Ring was not completely cleaned, so fire another interrupt */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
		ew32(ICS, tx_ring->ims_val);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
	return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
	struct net_device *netdev = data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	/* Write the ITR value calculated at the end of the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	 * previous interrupt.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	if (adapter->rx_ring->set_itr) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		writel(1000000000 / (adapter->rx_ring->itr_val * 256),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
		       adapter->hw.hw_addr + adapter->rx_ring->itr_register);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
		adapter->rx_ring->set_itr = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1724
	if (adapter->ecdev) {
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1725
		int ec_work_done = 0;
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  1726
		adapter->clean_rx(adapter, &ec_work_done, 100);
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		if (napi_schedule_prep(&adapter->napi)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
			adapter->total_rx_bytes = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
			adapter->total_rx_packets = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
			__napi_schedule(&adapter->napi);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
	return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
 * e1000_configure_msix - Configure MSI-X hardware
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
 * e1000_configure_msix sets up the hardware to properly
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
 * generate MSI-X interrupts.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
static void e1000_configure_msix(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	int vector = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
	u32 ctrl_ext, ivar = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	adapter->eiac_mask = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	if (hw->mac.type == e1000_82574) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
		u32 rfctl = er32(RFCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		rfctl |= E1000_RFCTL_ACK_DIS;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
		ew32(RFCTL, rfctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
#define E1000_IVAR_INT_ALLOC_VALID	0x8
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	/* Configure Rx vector */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	rx_ring->ims_val = E1000_IMS_RXQ0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	adapter->eiac_mask |= rx_ring->ims_val;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	if (rx_ring->itr_val)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
		writel(1000000000 / (rx_ring->itr_val * 256),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
		       hw->hw_addr + rx_ring->itr_register);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
		writel(1, hw->hw_addr + rx_ring->itr_register);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	/* Configure Tx vector */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	tx_ring->ims_val = E1000_IMS_TXQ0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
	vector++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	if (tx_ring->itr_val)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		writel(1000000000 / (tx_ring->itr_val * 256),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
		       hw->hw_addr + tx_ring->itr_register);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		writel(1, hw->hw_addr + tx_ring->itr_register);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	adapter->eiac_mask |= tx_ring->ims_val;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
	/* set vector for Other Causes, e.g. link changes */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	vector++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	if (rx_ring->itr_val)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
		writel(1000000000 / (rx_ring->itr_val * 256),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
		       hw->hw_addr + E1000_EITR_82574(vector));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
	/* Cause Tx interrupts on every write back */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	ivar |= (1 << 31);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	ew32(IVAR, ivar);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	/* enable MSI-X PBA support */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	ctrl_ext = er32(CTRL_EXT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	/* Auto-Mask Other interrupts upon ICR read */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
#define E1000_EIAC_MASK_82574   0x01F00000
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
	ew32(CTRL_EXT, ctrl_ext);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
	e1e_flush();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
	if (adapter->msix_entries) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
		pci_disable_msix(adapter->pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
		kfree(adapter->msix_entries);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
		adapter->msix_entries = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		pci_disable_msi(adapter->pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		adapter->flags &= ~FLAG_MSI_ENABLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
 * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
 * Attempt to configure interrupts using the best available
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
 * capabilities of the hardware and kernel.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	int err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
	int numvecs, i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
	switch (adapter->int_mode) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	case E1000E_INT_MODE_MSIX:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		if (adapter->flags & FLAG_HAS_MSIX) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
			numvecs = 3; /* RxQ0, TxQ0 and other */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
			adapter->msix_entries = kcalloc(numvecs,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
						      sizeof(struct msix_entry),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
						      GFP_KERNEL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
			if (adapter->msix_entries) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
				for (i = 0; i < numvecs; i++)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
					adapter->msix_entries[i].entry = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
				err = pci_enable_msix(adapter->pdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
						      adapter->msix_entries,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
						      numvecs);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
				if (err == 0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
					return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
			/* MSI-X failed, so fall through and try MSI */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
			e_err("Failed to initialize MSI-X interrupts.  "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
			      "Falling back to MSI interrupts.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			e1000e_reset_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
		adapter->int_mode = E1000E_INT_MODE_MSI;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
		/* Fall through */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
	case E1000E_INT_MODE_MSI:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
		if (!pci_enable_msi(adapter->pdev)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
			adapter->flags |= FLAG_MSI_ENABLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
			e_err("Failed to initialize MSI interrupts.  Falling "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
			      "back to legacy interrupts.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
		/* Fall through */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
	case E1000E_INT_MODE_LEGACY:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
		/* Don't do anything; this is the system default */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
 * e1000_request_msix - Initialize MSI-X interrupts
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
 * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
 * kernel.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
static int e1000_request_msix(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	int err = 0, vector = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
	err = request_irq(adapter->msix_entries[vector].vector,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
			  netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		goto out;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	adapter->rx_ring->itr_register = E1000_EITR_82574(vector);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
	adapter->rx_ring->itr_val = adapter->itr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
	vector++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
		sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
	err = request_irq(adapter->msix_entries[vector].vector,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
			  netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
		goto out;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	adapter->tx_ring->itr_register = E1000_EITR_82574(vector);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	adapter->tx_ring->itr_val = adapter->itr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	vector++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	err = request_irq(adapter->msix_entries[vector].vector,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
			  e1000_msix_other, 0, netdev->name, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		goto out;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
	e1000_configure_msix(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
out:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
 * e1000_request_irq - initialize interrupts
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
 * Attempts to configure interrupts using the best available
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
 * capabilities of the hardware and kernel.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
static int e1000_request_irq(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	int err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	if (adapter->msix_entries) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
		err = e1000_request_msix(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
		if (!err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
			return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		/* fall back to MSI */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
		e1000e_reset_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
		adapter->int_mode = E1000E_INT_MODE_MSI;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
		e1000e_set_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
	if (adapter->flags & FLAG_MSI_ENABLED) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
		err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
				  netdev->name, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		if (!err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
			return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
		/* fall back to legacy interrupt */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		e1000e_reset_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
	err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
			  netdev->name, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
		e_err("Unable to allocate interrupt, Error: %d\n", err);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
static void e1000_free_irq(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
	if (adapter->msix_entries) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
		int vector = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		free_irq(adapter->msix_entries[vector].vector, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		vector++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
		free_irq(adapter->msix_entries[vector].vector, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
		vector++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		/* Other Causes interrupt vector */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		free_irq(adapter->msix_entries[vector].vector, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	free_irq(adapter->pdev->irq, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
 * e1000_irq_disable - Mask off interrupt generation on the NIC
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
static void e1000_irq_disable(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	ew32(IMC, ~0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	if (adapter->msix_entries)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		ew32(EIAC_82574, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
	e1e_flush();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	synchronize_irq(adapter->pdev->irq);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
 * e1000_irq_enable - Enable default interrupt generation settings
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
static void e1000_irq_enable(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	if (adapter->msix_entries) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		ew32(IMS, IMS_ENABLE_MASK);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	e1e_flush();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
 * e1000_get_hw_control - get control of the h/w from f/w
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
 * @adapter: address of board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
 * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
 * For ASF and Pass Through versions of f/w this means that
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
 * the driver is loaded. For AMT version (only with 82573)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
 * of the f/w this means that the network i/f is open.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
static void e1000_get_hw_control(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	u32 ctrl_ext;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
	u32 swsm;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
	/* Let firmware know the driver has taken over */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		swsm = er32(SWSM);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		ctrl_ext = er32(CTRL_EXT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
 * e1000_release_hw_control - release control of the h/w to f/w
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
 * @adapter: address of board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
 * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
 * For ASF and Pass Through versions of f/w this means that the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
 * driver is no longer loaded. For AMT version (only with 82573) i
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
 * of the f/w this means that the network i/f is closed.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
static void e1000_release_hw_control(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
	u32 ctrl_ext;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	u32 swsm;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	/* Let firmware taken over control of h/w */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		swsm = er32(SWSM);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		ctrl_ext = er32(CTRL_EXT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
 * @e1000_alloc_ring - allocate memory for a ring structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
				struct e1000_ring *ring)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
					GFP_KERNEL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
	if (!ring->desc)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
		return -ENOMEM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
 * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
 * Return 0 on success, negative on failure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
	int err = -ENOMEM, size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
	size = sizeof(struct e1000_buffer) * tx_ring->count;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
	tx_ring->buffer_info = vmalloc(size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
	if (!tx_ring->buffer_info)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		goto err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	memset(tx_ring->buffer_info, 0, size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	/* round up to nearest 4K */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
	tx_ring->size = ALIGN(tx_ring->size, 4096);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	err = e1000_alloc_ring_dma(adapter, tx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
		goto err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
	tx_ring->next_to_use = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
	tx_ring->next_to_clean = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
err:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
	vfree(tx_ring->buffer_info);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
 * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
 * Returns 0 on success, negative on failure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	int i, size, desc_len, err = -ENOMEM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	size = sizeof(struct e1000_buffer) * rx_ring->count;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	rx_ring->buffer_info = vmalloc(size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	if (!rx_ring->buffer_info)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
		goto err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	memset(rx_ring->buffer_info, 0, size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	for (i = 0; i < rx_ring->count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
		buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
						sizeof(struct e1000_ps_page),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
						GFP_KERNEL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		if (!buffer_info->ps_pages)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
			goto err_pages;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	desc_len = sizeof(union e1000_rx_desc_packet_split);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	/* Round up to nearest 4K */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
	rx_ring->size = rx_ring->count * desc_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	rx_ring->size = ALIGN(rx_ring->size, 4096);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	err = e1000_alloc_ring_dma(adapter, rx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
		goto err_pages;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
	rx_ring->next_to_clean = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	rx_ring->next_to_use = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	rx_ring->rx_skb_top = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
err_pages:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
	for (i = 0; i < rx_ring->count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
		buffer_info = &rx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
		kfree(buffer_info->ps_pages);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
err:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
	vfree(rx_ring->buffer_info);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
 * e1000_clean_tx_ring - Free Tx Buffers
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
	unsigned long size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	for (i = 0; i < tx_ring->count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
		buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
		e1000_put_txbuf(adapter, buffer_info);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	size = sizeof(struct e1000_buffer) * tx_ring->count;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	memset(tx_ring->buffer_info, 0, size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
	memset(tx_ring->desc, 0, tx_ring->size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	tx_ring->next_to_use = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	tx_ring->next_to_clean = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	writel(0, adapter->hw.hw_addr + tx_ring->head);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	writel(0, adapter->hw.hw_addr + tx_ring->tail);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
 * e1000e_free_tx_resources - Free Tx Resources per Queue
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
 * Free all transmit software resources
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
void e1000e_free_tx_resources(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
	e1000_clean_tx_ring(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	vfree(tx_ring->buffer_info);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
	tx_ring->buffer_info = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
			  tx_ring->dma);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	tx_ring->desc = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
 * e1000e_free_rx_resources - Free Rx Resources
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
 * Free all receive software resources
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
void e1000e_free_rx_resources(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	e1000_clean_rx_ring(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
	for (i = 0; i < rx_ring->count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		kfree(rx_ring->buffer_info[i].ps_pages);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	vfree(rx_ring->buffer_info);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	rx_ring->buffer_info = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
			  rx_ring->dma);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	rx_ring->desc = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
 * e1000_update_itr - update the dynamic ITR value based on statistics
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
 * @adapter: pointer to adapter
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
 * @itr_setting: current adapter->itr
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
 * @packets: the number of packets during this measurement interval
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
 * @bytes: the number of bytes during this measurement interval
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
 *      Stores a new ITR value based on packets and byte
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
 *      counts during the last interrupt.  The advantage of per interrupt
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
 *      computation is faster updates and more accurate ITR for the current
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
 *      traffic pattern.  Constants in this function were computed
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
 *      based on theoretical maximum wire speed and thresholds were set based
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
 *      on testing data as well as attempting to minimize response time
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
 *      while increasing bulk throughput.  This functionality is controlled
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
 *      by the InterruptThrottleRate module parameter.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
				     u16 itr_setting, int packets,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
				     int bytes)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
	unsigned int retval = itr_setting;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
	if (packets == 0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
		goto update_itr_done;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	switch (itr_setting) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	case lowest_latency:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
		/* handle TSO and jumbo frames */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
		if (bytes/packets > 8000)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
			retval = bulk_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
		else if ((packets < 5) && (bytes > 512)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
			retval = low_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	case low_latency:  /* 50 usec aka 20000 ints/s */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
		if (bytes > 10000) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
			/* this if handles the TSO accounting */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
			if (bytes/packets > 8000) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
				retval = bulk_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
			} else if ((packets < 10) || ((bytes/packets) > 1200)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
				retval = bulk_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
			} else if ((packets > 35)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
				retval = lowest_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
		} else if (bytes/packets > 2000) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
			retval = bulk_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
		} else if (packets <= 2 && bytes < 512) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
			retval = lowest_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	case bulk_latency: /* 250 usec aka 4000 ints/s */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
		if (bytes > 25000) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
			if (packets > 35) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
				retval = low_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
		} else if (bytes < 6000) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
			retval = low_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
update_itr_done:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	return retval;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
static void e1000_set_itr(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	u16 current_itr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	u32 new_itr = adapter->itr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
	if (adapter->link_speed != SPEED_1000) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		current_itr = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		new_itr = 4000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
		goto set_itr_now;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	adapter->tx_itr = e1000_update_itr(adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
				    adapter->tx_itr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
				    adapter->total_tx_packets,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
				    adapter->total_tx_bytes);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		adapter->tx_itr = low_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
	adapter->rx_itr = e1000_update_itr(adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
				    adapter->rx_itr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
				    adapter->total_rx_packets,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
				    adapter->total_rx_bytes);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		adapter->rx_itr = low_latency;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
	switch (current_itr) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	/* counts and packets in update_itr are dependent on these numbers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	case lowest_latency:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
		new_itr = 70000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	case low_latency:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
		new_itr = 20000; /* aka hwitr = ~200 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
	case bulk_latency:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
		new_itr = 4000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
set_itr_now:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	if (new_itr != adapter->itr) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
		 * this attempts to bias the interrupt rate towards Bulk
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
		 * by adding intermediate steps when interrupt rate is
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
		 * increasing
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
		new_itr = new_itr > adapter->itr ?
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
			     min(adapter->itr + (new_itr >> 2), new_itr) :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
			     new_itr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
		adapter->itr = new_itr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
		adapter->rx_ring->itr_val = new_itr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
		if (adapter->msix_entries)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
			adapter->rx_ring->set_itr = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
		else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
			ew32(ITR, 1000000000 / (new_itr * 256));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
 * e1000_alloc_queues - Allocate memory for all rings
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
 * @adapter: board private structure to initialize
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
	adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	if (!adapter->tx_ring)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		goto err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	if (!adapter->rx_ring)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
		goto err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
err:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
	e_err("Unable to allocate memory for queues\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
	kfree(adapter->rx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
	kfree(adapter->tx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
	return -ENOMEM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
 * e1000_clean - NAPI Rx polling callback
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
 * @napi: struct associated with this polling callback
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
 * @budget: amount of packets driver is allowed to process this poll
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
static int e1000_clean(struct napi_struct *napi, int budget)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	struct net_device *poll_dev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	int tx_cleaned = 1, work_done = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
	adapter = netdev_priv(poll_dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	if (adapter->msix_entries &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
	    !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
		goto clean_rx;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
	tx_cleaned = e1000_clean_tx_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
clean_rx:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	adapter->clean_rx(adapter, &work_done, budget);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	if (!tx_cleaned)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
		work_done = budget;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	/* If budget not fully consumed, exit the polling mode */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	if (work_done < budget) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
		if (adapter->itr_setting & 3)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
			e1000_set_itr(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
		napi_complete(napi);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
			if (adapter->msix_entries)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
				ew32(IMS, adapter->rx_ring->ims_val);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
			else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
				e1000_irq_enable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	return work_done;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
	u32 vfta, index;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
	/* don't update vlan cookie if already programmed */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
	if ((adapter->hw.mng_cookie.status &
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
	    (vid == adapter->mng_vlan_id))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
	/* add VID to filter table */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
		index = (vid >> 5) & 0x7F;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
		vfta |= (1 << (vid & 0x1F));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
		hw->mac.ops.write_vfta(hw, index, vfta);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	u32 vfta, index;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
	if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
		e1000_irq_disable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
		e1000_irq_enable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	if ((adapter->hw.mng_cookie.status &
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
	    (vid == adapter->mng_vlan_id)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
		/* release control to f/w */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
		e1000_release_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	/* remove VID from filter table */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
		index = (vid >> 5) & 0x7F;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
		vfta &= ~(1 << (vid & 0x1F));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
		hw->mac.ops.write_vfta(hw, index, vfta);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	u16 vid = adapter->hw.mng_cookie.vlan_id;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	u16 old_vid = adapter->mng_vlan_id;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
	if (!adapter->vlgrp)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	if (!vlan_group_get_device(adapter->vlgrp, vid)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		if (adapter->hw.mng_cookie.status &
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
			e1000_vlan_rx_add_vid(netdev, vid);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
			adapter->mng_vlan_id = vid;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
				(vid != old_vid) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
		    !vlan_group_get_device(adapter->vlgrp, old_vid))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
			e1000_vlan_rx_kill_vid(netdev, old_vid);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
		adapter->mng_vlan_id = vid;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
static void e1000_vlan_rx_register(struct net_device *netdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
				   struct vlan_group *grp)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
	u32 ctrl, rctl;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
	if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
		e1000_irq_disable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
	adapter->vlgrp = grp;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	if (grp) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
		/* enable VLAN tag insert/strip */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
		ctrl = er32(CTRL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
		ctrl |= E1000_CTRL_VME;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
		ew32(CTRL, ctrl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
			/* enable VLAN receive filtering */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
			rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
			rctl &= ~E1000_RCTL_CFIEN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
			ew32(RCTL, rctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
			e1000_update_mng_vlan(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
		/* disable VLAN tag insert/strip */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
		ctrl = er32(CTRL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
		ctrl &= ~E1000_CTRL_VME;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
		ew32(CTRL, ctrl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
			if (adapter->mng_vlan_id !=
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
			    (u16)E1000_MNG_VLAN_NONE) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
				e1000_vlan_rx_kill_vid(netdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
						       adapter->mng_vlan_id);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
	if (!test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
		e1000_irq_enable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
static void e1000_restore_vlan(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
	u16 vid;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	if (!adapter->vlgrp)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
		if (!vlan_group_get_device(adapter->vlgrp, vid))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
			continue;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
		e1000_vlan_rx_add_vid(adapter->netdev, vid);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
	u32 manc, manc2h, mdef, i, j;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
	manc = er32(MANC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	 * enable receiving management packets to the host. this will probably
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	 * generate destination unreachable messages from the host OS, but
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
	 * the packets will be handled on SMBUS
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
	manc |= E1000_MANC_EN_MNG2HOST;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
	manc2h = er32(MANC2H);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	switch (hw->mac.type) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
		manc2h |= (E1000_MANC2H_PORT_623 | E1000_MANC2H_PORT_664);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
	case e1000_82574:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
	case e1000_82583:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
		 * Check if IPMI pass-through decision filter already exists;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		 * if so, enable it.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
		for (i = 0, j = 0; i < 8; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
			mdef = er32(MDEF(i));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
			/* Ignore filters with anything other than IPMI ports */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
			if (mdef & ~(E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
				continue;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
			/* Enable this decision filter in MANC2H */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
			if (mdef)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
				manc2h |= (1 << i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
			j |= mdef;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
		if (j == (E1000_MDEF_PORT_623 | E1000_MDEF_PORT_664))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
		/* Create new decision filter in an empty filter */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
		for (i = 0, j = 0; i < 8; i++)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
			if (er32(MDEF(i)) == 0) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
				ew32(MDEF(i), (E1000_MDEF_PORT_623 |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
					       E1000_MDEF_PORT_664));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
				manc2h |= (1 << 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
				j++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
				break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
		if (!j)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
			e_warn("Unable to create IPMI pass-through filter\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	ew32(MANC2H, manc2h);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	ew32(MANC, manc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
 * Configure the Tx unit of the MAC after a reset.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
static void e1000_configure_tx(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
	u64 tdba;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
	u32 tdlen, tctl, tipg, tarc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	u32 ipgr1, ipgr2;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
	/* Setup the HW Tx Head and Tail descriptor pointers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
	tdba = tx_ring->dma;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
	ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
	ew32(TDBAH, (tdba >> 32));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
	ew32(TDLEN, tdlen);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
	ew32(TDH, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
	ew32(TDT, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
	tx_ring->head = E1000_TDH;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	tx_ring->tail = E1000_TDT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
	/* Set the default values for the Tx Inter Packet Gap timer */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
	tipg = DEFAULT_82543_TIPG_IPGT_COPPER;          /*  8  */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	ipgr1 = DEFAULT_82543_TIPG_IPGR1;               /*  8  */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
	ipgr2 = DEFAULT_82543_TIPG_IPGR2;               /*  6  */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
	if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /*  7  */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
	ew32(TIPG, tipg);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
	/* Set the Tx Interrupt Delay register */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	ew32(TIDV, adapter->tx_int_delay);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
	/* Tx irq moderation */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
	ew32(TADV, adapter->tx_abs_int_delay);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
	/* Program the Transmit Control Register */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
	tctl = er32(TCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
	tctl &= ~E1000_TCTL_CT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
		tarc = er32(TARC(0));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
		 * set the speed mode bit, we'll clear it if we're not at
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
		 * gigabit link later
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
#define SPEED_MODE_BIT (1 << 21)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
		tarc |= SPEED_MODE_BIT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
		ew32(TARC(0), tarc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
	/* errata: program both queues to unweighted RR */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		tarc = er32(TARC(0));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
		tarc |= 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		ew32(TARC(0), tarc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
		tarc = er32(TARC(1));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		tarc |= 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
		ew32(TARC(1), tarc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
	/* Setup Transmit Descriptor Settings for eop descriptor */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
	/* only set IDE if we are delaying interrupts using the timers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	if (adapter->tx_int_delay)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
	/* enable Report Status bit */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
	ew32(TCTL, tctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
	e1000e_config_collision_dist(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
 * e1000_setup_rctl - configure the receive control registers
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
 * @adapter: Board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
static void e1000_setup_rctl(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
	u32 rctl, rfctl;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
	u32 psrctl = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
	u32 pages = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
	/* Program MC offset vector base */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
	rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
		(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
	/* Do not Store bad packets */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	rctl &= ~E1000_RCTL_SBP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	/* Enable Long Packet receive */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
		rctl &= ~E1000_RCTL_LPE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
		rctl |= E1000_RCTL_LPE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	/* Some systems expect that the CRC is included in SMBUS traffic. The
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
	 * hardware strips the CRC before sending to both SMBUS (BMC) and to
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	 * host memory when this is enabled
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		rctl |= E1000_RCTL_SECRC;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
	/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
	if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
		u16 phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		phy_data &= 0xfff8;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		phy_data |= (1 << 2);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		e1e_wphy(hw, PHY_REG(770, 26), phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		e1e_rphy(hw, 22, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		phy_data &= 0x0fff;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		phy_data |= (1 << 14);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		e1e_wphy(hw, 0x10, 0x2823);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		e1e_wphy(hw, 0x11, 0x0003);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		e1e_wphy(hw, 22, phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
	/* Setup buffer sizes */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	rctl &= ~E1000_RCTL_SZ_4096;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
	rctl |= E1000_RCTL_BSEX;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	switch (adapter->rx_buffer_len) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
	case 2048:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		rctl |= E1000_RCTL_SZ_2048;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		rctl &= ~E1000_RCTL_BSEX;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
	case 4096:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		rctl |= E1000_RCTL_SZ_4096;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	case 8192:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
		rctl |= E1000_RCTL_SZ_8192;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
	case 16384:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		rctl |= E1000_RCTL_SZ_16384;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
	 * 82571 and greater support packet-split where the protocol
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
	 * header is placed in skb->data and the packet data is
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
	 * In the case of a non-split, skb->data is linearly filled,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
	 * followed by the page buffers.  Therefore, skb->data is
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	 * sized to hold the largest protocol header.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
	 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
	 * allocations using alloc_page take too long for regular MTU
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	 * so only enable packet split for jumbo frames
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	 * Using pages when the page size is greater than 16k wastes
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	 * a lot of memory, since we allocate 3 pages at all times
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	 * per packet.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	    (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
		adapter->rx_ps_pages = pages;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
		adapter->rx_ps_pages = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
	if (adapter->rx_ps_pages) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		/* Configure extra packet-split registers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		rfctl = er32(RFCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
		rfctl |= E1000_RFCTL_EXTEN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
		 * disable packet split support for IPv6 extension headers,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
		 * because some malformed IPv6 headers can hang the Rx
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
			  E1000_RFCTL_NEW_IPV6_EXT_DIS);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		ew32(RFCTL, rfctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
		/* Enable Packet split descriptors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
		rctl |= E1000_RCTL_DTYP_PS;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
		psrctl |= adapter->rx_ps_bsize0 >>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
			E1000_PSRCTL_BSIZE0_SHIFT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		switch (adapter->rx_ps_pages) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		case 3:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
			psrctl |= PAGE_SIZE <<
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
				E1000_PSRCTL_BSIZE3_SHIFT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
		case 2:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
			psrctl |= PAGE_SIZE <<
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
				E1000_PSRCTL_BSIZE2_SHIFT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		case 1:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
			psrctl |= PAGE_SIZE >>
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
				E1000_PSRCTL_BSIZE1_SHIFT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
		ew32(PSRCTL, psrctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	ew32(RCTL, rctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	/* just started the receive unit, no need to restart */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	adapter->flags &= ~FLAG_RX_RESTART_NOW;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
 * e1000_configure_rx - Configure Receive Unit after Reset
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
 * Configure the Rx unit of the MAC after a reset.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
static void e1000_configure_rx(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	struct e1000_ring *rx_ring = adapter->rx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	u64 rdba;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	u32 rdlen, rctl, rxcsum, ctrl_ext;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	if (adapter->rx_ps_pages) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
		/* this is a 32 byte descriptor */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
		rdlen = rx_ring->count *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
			sizeof(union e1000_rx_desc_packet_split);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
		adapter->clean_rx = e1000_clean_rx_irq_ps;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		adapter->clean_rx = e1000_clean_rx_irq;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	/* disable receives while setting up the descriptors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	e1e_flush();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
	msleep(10);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	/* set the Receive Delay Timer Register */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	ew32(RDTR, adapter->rx_int_delay);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	/* irq moderation */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	ew32(RADV, adapter->rx_abs_int_delay);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
	if (adapter->itr_setting != 0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
		ew32(ITR, 1000000000 / (adapter->itr * 256));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	ctrl_ext = er32(CTRL_EXT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	/* Auto-Mask interrupts upon ICR access */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
	ctrl_ext |= E1000_CTRL_EXT_IAME;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	ew32(IAM, 0xffffffff);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
	ew32(CTRL_EXT, ctrl_ext);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
	e1e_flush();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	 * Setup the HW Rx Head and Tail Descriptor Pointers and
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	 * the Base and Length of the Rx Descriptor Ring
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	rdba = rx_ring->dma;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	ew32(RDBAH, (rdba >> 32));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
	ew32(RDLEN, rdlen);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
	ew32(RDH, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
	ew32(RDT, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
	rx_ring->head = E1000_RDH;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
	rx_ring->tail = E1000_RDT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
	/* Enable Receive Checksum Offload for TCP and UDP */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
	rxcsum = er32(RXCSUM);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
	if (adapter->flags & FLAG_RX_CSUM_ENABLED) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
		rxcsum |= E1000_RXCSUM_TUOFL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
		 * IPv4 payload checksum for UDP fragments must be
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
		 * used in conjunction with packet-split.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
		if (adapter->rx_ps_pages)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
			rxcsum |= E1000_RXCSUM_IPPCSE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
		rxcsum &= ~E1000_RXCSUM_TUOFL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
		/* no need to clear IPPCSE as it defaults to 0 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	ew32(RXCSUM, rxcsum);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	 * Enable early receives on supported devices, only takes effect when
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2950
	 * packet size is equal or larger than the specified value (in 8 byte
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	if (adapter->flags & FLAG_HAS_ERT) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
			u32 rxdctl = er32(RXDCTL(0));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
			ew32(RXDCTL(0), rxdctl | 0x3);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
			ew32(ERT, E1000_ERT_2048 | (1 << 13));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
			 * With jumbo frames and early-receive enabled,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
			 * excessive C-state transition latencies result in
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
			 * dropped transactions.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
			pm_qos_update_request(
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
				adapter->netdev->pm_qos_req, 55);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
			pm_qos_update_request(
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
				adapter->netdev->pm_qos_req,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
				PM_QOS_DEFAULT_VALUE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	/* Enable Receives */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	ew32(RCTL, rctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
 *  e1000_update_mc_addr_list - Update Multicast addresses
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
 *  @hw: pointer to the HW structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
 *  @mc_addr_list: array of multicast addresses to program
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
 *  @mc_addr_count: number of multicast addresses to program
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
 *  Updates the Multicast Table Array.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
 *  The caller must have a packed mc_addr_list of multicast addresses.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
				      u32 mc_addr_count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
	hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
 * e1000_set_multi - Multicast and Promiscuous mode set
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
 * @netdev: network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
 * The set_multi entry point is called whenever the multicast address
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
 * list or the network interface flags are updated.  This routine is
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
 * responsible for configuring the hardware for proper multicast,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
 * promiscuous mode, and all-multi behavior.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
static void e1000_set_multi(struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
	struct netdev_hw_addr *ha;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	u8  *mta_list;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
	u32 rctl;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
	int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
	/* Check for Promiscuous and All Multicast modes */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
	rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	if (netdev->flags & IFF_PROMISC) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
		rctl &= ~E1000_RCTL_VFE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
		if (netdev->flags & IFF_ALLMULTI) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
			rctl |= E1000_RCTL_MPE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
			rctl &= ~E1000_RCTL_UPE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
			rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
			rctl |= E1000_RCTL_VFE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
	ew32(RCTL, rctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
	if (!netdev_mc_empty(netdev)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
		mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
		if (!mta_list)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
			return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
		/* prepare a packed array of only addresses. */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
		i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
		netdev_for_each_mc_addr(ha, netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
			memcpy(mta_list + (i++ * ETH_ALEN), ha->addr, ETH_ALEN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
		e1000_update_mc_addr_list(hw, mta_list, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
		kfree(mta_list);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		 * if we're called from probe, we might not have
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		 * anything to do here, so clear out the list
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
		e1000_update_mc_addr_list(hw, NULL, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
 * e1000_configure - configure the hardware for Rx and Tx
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
 * @adapter: private board structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
static void e1000_configure(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
	e1000_set_multi(adapter->netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	e1000_restore_vlan(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	e1000_init_manageability_pt(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
	e1000_configure_tx(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	e1000_setup_rctl(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	e1000_configure_rx(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
	if (adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
		adapter->alloc_rx_buf(adapter, adapter->rx_ring->count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
		adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
 * e1000e_power_up_phy - restore link in case the phy was powered down
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
 * @adapter: address of board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
 * The phy may be powered down to save power and turn off link when the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
 * driver is unloaded and wake on lan is not enabled (among others)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
 * *** this routine MUST be followed by a call to e1000e_reset ***
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
void e1000e_power_up_phy(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	if (adapter->hw.phy.ops.power_up)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
		adapter->hw.phy.ops.power_up(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	adapter->hw.mac.ops.setup_link(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
 * e1000_power_down_phy - Power down the PHY
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
 * Power down the PHY so no link is implied when interface is down.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
 * The PHY cannot be powered down if management or WoL is active.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
static void e1000_power_down_phy(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	/* WoL is enabled */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
	if (adapter->wol)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
	if (adapter->hw.phy.ops.power_down)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		adapter->hw.phy.ops.power_down(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
 * e1000e_reset - bring the hardware into a known good state
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
 * This function boots the hardware and enables some settings that
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
 * require a configuration cycle of the hardware - those cannot be
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
 * set/changed during runtime. After reset the device needs to be
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
 * properly configured for Rx, Tx etc.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
void e1000e_reset(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	struct e1000_mac_info *mac = &adapter->hw.mac;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	struct e1000_fc_info *fc = &adapter->hw.fc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	u32 tx_space, min_tx_space, min_rx_space;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	u32 pba = adapter->pba;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
	u16 hwm;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	/* reset Packet Buffer Allocation to default */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
	ew32(PBA, pba);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
		 * To maintain wire speed transmits, the Tx FIFO should be
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
		 * large enough to accommodate two full transmit packets,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
		 * the Rx FIFO should be large enough to accommodate at least
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
		 * one full receive packet and is similarly rounded up and
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
		 * expressed in KB.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
		pba = er32(PBA);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
		/* upper 16 bits has Tx packet buffer allocation size in KB */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
		tx_space = pba >> 16;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
		/* lower 16 bits has Rx packet buffer allocation size in KB */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
		pba &= 0xffff;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
		 * the Tx fifo also stores 16 bytes of information about the tx
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
		 * but don't include ethernet FCS because hardware appends it
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
		min_tx_space = (adapter->max_frame_size +
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
				sizeof(struct e1000_tx_desc) -
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
				ETH_FCS_LEN) * 2;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
		min_tx_space = ALIGN(min_tx_space, 1024);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
		min_tx_space >>= 10;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
		/* software strips receive CRC, so leave room for it */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		min_rx_space = adapter->max_frame_size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
		min_rx_space = ALIGN(min_rx_space, 1024);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
		min_rx_space >>= 10;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
		 * If current Tx allocation is less than the min Tx FIFO size,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		 * and the min Tx FIFO size is less than the current Rx FIFO
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
		 * allocation, take space away from current Rx allocation
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		if ((tx_space < min_tx_space) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
		    ((min_tx_space - tx_space) < pba)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
			pba -= min_tx_space - tx_space;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
			 * if short on Rx space, Rx wins and must trump tx
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
			 * adjustment or use Early Receive if available
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
			if ((pba < min_rx_space) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
			    (!(adapter->flags & FLAG_HAS_ERT)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
				/* ERT enabled in e1000_configure_rx */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
				pba = min_rx_space;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
		ew32(PBA, pba);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	 * flow control settings
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	 * The high water mark must be low enough to fit one full frame
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	 * (or the size used for early receive) above it in the Rx FIFO.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
	 * Set it to the lower of:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	 * - 90% of the Rx FIFO size, and
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	 * - the full Rx FIFO size minus the early receive size (for parts
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	 * - the full Rx FIFO size minus one full frame
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	if (hw->mac.type == e1000_pchlan) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
		 * Workaround PCH LOM adapter hangs with certain network
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
		 * loads.  If hangs persist, try disabling Tx flow control.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
			fc->high_water = 0x3500;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
			fc->low_water  = 0x1500;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
			fc->high_water = 0x5000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
			fc->low_water  = 0x3000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
		fc->refresh_time = 0x1000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
		if ((adapter->flags & FLAG_HAS_ERT) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
		    (adapter->netdev->mtu > ETH_DATA_LEN))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
			hwm = min(((pba << 10) * 9 / 10),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
				  ((pba << 10) - (E1000_ERT_2048 << 3)));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
		else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
			hwm = min(((pba << 10) * 9 / 10),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
				  ((pba << 10) - adapter->max_frame_size));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
		fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
		fc->low_water = fc->high_water - 8;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
		fc->pause_time = 0xFFFF;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
		fc->pause_time = E1000_FC_PAUSE_TIME;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	fc->send_xon = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	fc->current_mode = fc->requested_mode;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
	/* Allow time for pending master requests to run */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	mac->ops.reset_hw(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	 * For parts with AMT enabled, let the firmware know
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	 * that the network interface is in control
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	if (adapter->flags & FLAG_HAS_AMT)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
		e1000_get_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	ew32(WUC, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		e1e_wphy(&adapter->hw, BM_WUC, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
	if (mac->ops.init_hw(hw))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
		e_err("Hardware Error\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
	e1000_update_mng_vlan(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
	ew32(VET, ETH_P_8021Q);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3241
	e1000e_reset_adaptive(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
	e1000_get_phy_info(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3244
	if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3245
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
		u16 phy_data = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
		 * speed up time to link by disabling smart power down, ignore
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
		 * the return value of this function because there is nothing
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
		 * different we would do if it failed
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
		phy_data &= ~IGP02E1000_PM_SPD;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
int e1000e_up(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	/* DMA latency requirement to workaround early-receive/jumbo issue */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
	if (adapter->flags & FLAG_HAS_ERT)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
		adapter->netdev->pm_qos_req =
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
			pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
				       PM_QOS_DEFAULT_VALUE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
	/* hardware has been reset, we need to reload some things */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
	e1000_configure(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
	clear_bit(__E1000_DOWN, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
	if (!adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
		napi_enable(&adapter->napi);
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3275
	}
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
	if (adapter->msix_entries)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
		e1000_configure_msix(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
	if (!adapter->ecdev) {
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3280
		e1000_irq_enable(adapter);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3281
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3282
		netif_wake_queue(adapter->netdev);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3283
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3284
		/* fire a link change interrupt to start the watchdog */
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3285
		if (adapter->msix_entries)
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3286
			ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3287
		else
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3288
			ew32(ICS, E1000_ICS_LSC);
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
void e1000e_down(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	u32 tctl, rctl;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	 * signal that we're down so the interrupt handler does not
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	 * reschedule our watchdog timer
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
	set_bit(__E1000_DOWN, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
	/* disable receives in the hardware */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
	rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
	/* flush and sleep below */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
2421
bc2d4bf9cbe5 Removed trailing spaces.
Florian Pose <fp@igh-essen.com>
parents: 2290
diff changeset
  3311
	if (!adapter->ecdev)
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
		netif_stop_queue(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	/* disable transmits in the hardware */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	tctl = er32(TCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	tctl &= ~E1000_TCTL_EN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	ew32(TCTL, tctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	/* flush both disables and wait for them to finish */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	e1e_flush();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
	msleep(10);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	if (!adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
		napi_disable(&adapter->napi);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
		e1000_irq_disable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
		del_timer_sync(&adapter->watchdog_timer);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
		del_timer_sync(&adapter->phy_info_timer);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
	if (adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
		ecdev_set_link(adapter->ecdev, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		netif_carrier_off(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
	adapter->link_speed = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
	adapter->link_duplex = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
	if (!pci_channel_offline(adapter->pdev))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
		e1000e_reset(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
	e1000_clean_tx_ring(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
	e1000_clean_rx_ring(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	if (adapter->flags & FLAG_HAS_ERT) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
		pm_qos_remove_request(
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
			      adapter->netdev->pm_qos_req);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		adapter->netdev->pm_qos_req = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	 * TODO: for power management, we could drop the link and
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	 * pci_disable_device here.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
void e1000e_reinit_locked(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	might_sleep();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
		msleep(1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
	e1000e_down(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	e1000e_up(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	clear_bit(__E1000_RESETTING, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
 * @adapter: board private structure to initialize
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
 * e1000_sw_init initializes the Adapter private data structure.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
 * Fields are initialized based on PCI device information and
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
 * OS network device settings (MTU size).
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	adapter->rx_ps_bsize0 = 128;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	e1000e_set_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	if (e1000_alloc_queues(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
		return -ENOMEM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	/* Explicitly disable IRQ since the NIC can be in any state. */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	e1000_irq_disable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	set_bit(__E1000_DOWN, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
 * e1000_intr_msi_test - Interrupt Handler
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
 * @irq: interrupt number
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
 * @data: pointer to a network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
static irqreturn_t e1000_intr_msi_test(int irq, void *data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	struct net_device *netdev = data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	u32 icr = er32(ICR);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
	e_dbg("icr is %08X\n", icr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
	if (icr & E1000_ICR_RXSEQ) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
		wmb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
	return IRQ_HANDLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
 * e1000_test_msi_interrupt - Returns 0 for successful test
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
 * @adapter: board private struct
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
 * code flow taken from tg3.c
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	int err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
	/* poll_enable hasn't been called yet, so don't need disable */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
	/* clear any pending events */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
	er32(ICR);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	/* free the real vector and request a test handler */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	e1000_free_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	e1000e_reset_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	/* Assume that the test fails, if it succeeds then the test
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	 * MSI irq handler will unset this flag */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	adapter->flags |= FLAG_MSI_TEST_FAILED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	err = pci_enable_msi(adapter->pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
		goto msi_test_failed;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
			  netdev->name, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	if (err) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
		pci_disable_msi(adapter->pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
		goto msi_test_failed;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
	wmb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	e1000_irq_enable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	/* fire an unusual interrupt on the test handler */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	ew32(ICS, E1000_ICS_RXSEQ);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
	e1e_flush();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	msleep(50);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	e1000_irq_disable(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
	rmb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		err = -EIO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		e_info("MSI interrupt test failed!\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	free_irq(adapter->pdev->irq, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	pci_disable_msi(adapter->pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	if (err == -EIO)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
		goto msi_test_failed;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	/* okay so the test worked, restore settings */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
	e_dbg("MSI interrupt test succeeded!\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
msi_test_failed:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	e1000e_set_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	e1000_request_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
 * @adapter: board private struct
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
 * code flow taken from tg3.c, called with e1000 interrupts disabled.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
static int e1000_test_msi(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
	int err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	u16 pci_cmd;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	if (!(adapter->flags & FLAG_MSI_ENABLED))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	/* disable SERR in case the MSI write causes a master abort */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
	if (pci_cmd & PCI_COMMAND_SERR)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
		pci_write_config_word(adapter->pdev, PCI_COMMAND,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
				      pci_cmd & ~PCI_COMMAND_SERR);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	err = e1000_test_msi_interrupt(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	/* re-enable SERR */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
	if (pci_cmd & PCI_COMMAND_SERR) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
		pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
		pci_cmd |= PCI_COMMAND_SERR;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
		pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
	/* success ! */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	if (!err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	/* EIO means MSI test failed */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	if (err != -EIO)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
		return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	/* back to INTx mode */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
	e_warn("MSI interrupt test failed, using legacy interrupt.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
	e1000_free_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
	err = e1000_request_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
 * e1000_open - Called when a network interface is made active
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
 * @netdev: network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
 * Returns 0 on success, negative value on failure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
 * The open entry point is called when a network interface is made
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
 * active by the system (IFF_UP).  At this point all resources needed
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
 * for transmit and receive operations are allocated, the interrupt
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
 * handler is registered with the OS, the watchdog timer is started,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
 * and the stack is notified that the interface is ready.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
static int e1000_open(struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
	int err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
	/* disallow open during test */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
	if (test_bit(__E1000_TESTING, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
		return -EBUSY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
	pm_runtime_get_sync(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	if (adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
		ecdev_set_link(adapter->ecdev, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
		netif_carrier_off(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	/* allocate transmit descriptors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	err = e1000e_setup_tx_resources(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
		goto err_setup_tx;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	/* allocate receive descriptors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	err = e1000e_setup_rx_resources(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
		goto err_setup_rx;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
	 * If AMT is enabled, let the firmware know that the network
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	 * interface is now open and reset the part to a known state.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	if (adapter->flags & FLAG_HAS_AMT) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
		e1000_get_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
		e1000e_reset(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	e1000e_power_up_phy(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
	if ((adapter->hw.mng_cookie.status &
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
		e1000_update_mng_vlan(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	 * before we allocate an interrupt, we must be ready to handle it.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
	 * as soon as we call pci_request_irq, so we have to setup our
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
	 * clean_rx handler before we do so.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
	e1000_configure(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
	err = e1000_request_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
		goto err_req_irq;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
	 * Work around PCIe errata with MSI interrupts causing some chipsets to
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	 * ignore e1000e MSI messages, which means we need to test our MSI
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	 * interrupt now
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
	if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
		err = e1000_test_msi(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
		if (err) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
			e_err("Interrupt allocation failed\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
			goto err_req_irq;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	/* From here on the code is the same as e1000e_up() */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	clear_bit(__E1000_DOWN, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3614
	if (!adapter->ecdev) {
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3615
		napi_enable(&adapter->napi);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3616
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3617
		e1000_irq_enable(adapter);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3618
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3619
		netif_start_queue(netdev);
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  3620
	}
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
	adapter->idle_check = true;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
	pm_runtime_put(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
	/* fire a link status change interrupt to start the watchdog */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
	if (adapter->msix_entries)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
		ew32(ICS, E1000_ICS_LSC | E1000_ICR_OTHER);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
		ew32(ICS, E1000_ICS_LSC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
err_req_irq:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
	e1000_release_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
	e1000_power_down_phy(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
	e1000e_free_rx_resources(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
err_setup_rx:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
	e1000e_free_tx_resources(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
err_setup_tx:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	e1000e_reset(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	pm_runtime_put_sync(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
 * e1000_close - Disables a network interface
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
 * @netdev: network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
 * Returns 0, this is not allowed to fail
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
 * The close entry point is called when an interface is de-activated
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
 * by the OS.  The hardware is still under the drivers control, but
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
 * needs to be disabled.  A global MAC reset is issued to stop the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
 * hardware, and all transmit and receive resources are freed.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
static int e1000_close(struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
	pm_runtime_get_sync(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
	if (!test_bit(__E1000_DOWN, &adapter->state)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
		e1000e_down(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
		e1000_free_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
	e1000_power_down_phy(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
	e1000e_free_tx_resources(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
	e1000e_free_rx_resources(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
	 * kill manageability vlan ID if supported, but not if a vlan with
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
	 * the same ID is registered on the host OS (let 8021q kill it)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
	if ((adapter->hw.mng_cookie.status &
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
	     !(adapter->vlgrp &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
	 * If AMT is enabled, let the firmware know that the network
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
	 * interface is now closed
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
	if (adapter->flags & FLAG_HAS_AMT)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
		e1000_release_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
	pm_runtime_put_sync(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
 * e1000_set_mac - Change the Ethernet Address of the NIC
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
 * @netdev: network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
 * @p: pointer to an address structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
 * Returns 0 on success, negative on failure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
static int e1000_set_mac(struct net_device *netdev, void *p)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
	struct sockaddr *addr = p;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
	if (!is_valid_ether_addr(addr->sa_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
		return -EADDRNOTAVAIL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
	e1000e_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
		/* activate the work around */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
		e1000e_set_laa_state_82571(&adapter->hw, 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
		 * Hold a copy of the LAA in RAR[14] This is done so that
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
		 * between the time RAR[0] gets clobbered  and the time it
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
		 * of the RARs and no incoming packets directed to this port
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
		 * are dropped. Eventually the LAA will be in RAR[0] and
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
		 * RAR[14]
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
		e1000e_rar_set(&adapter->hw,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
			      adapter->hw.mac.addr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
			      adapter->hw.mac.rar_entry_count - 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
 * e1000e_update_phy_task - work thread to update phy
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
 * @work: pointer to our work struct
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
 * this worker thread exists because we must acquire a
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
 * semaphore to read the phy, which we could msleep while
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
 * waiting for it, and we can't msleep in a timer.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
static void e1000e_update_phy_task(struct work_struct *work)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
	struct e1000_adapter *adapter = container_of(work,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
					struct e1000_adapter, update_phy_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	e1000_get_phy_info(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
 * Need to wait a few seconds after link up to get diagnostic information from
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
 * the phy
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
static void e1000_update_phy_info(unsigned long data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
	schedule_work(&adapter->update_phy_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
 * e1000e_update_stats - Update the board statistics counters
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
void e1000e_update_stats(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	u16 phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
	 * Prevent stats update while adapter is being reset, or if the pci
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
	 * connection is down.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
	if (adapter->link_speed == 0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
	if (pci_channel_offline(pdev))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	adapter->stats.crcerrs += er32(CRCERRS);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
	adapter->stats.gprc += er32(GPRC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	adapter->stats.gorc += er32(GORCL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
	er32(GORCH); /* Clear gorc */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	adapter->stats.bprc += er32(BPRC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
	adapter->stats.mprc += er32(MPRC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
	adapter->stats.roc += er32(ROC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
	adapter->stats.mpc += er32(MPC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	if ((hw->phy.type == e1000_phy_82578) ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	    (hw->phy.type == e1000_phy_82577)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
			adapter->stats.scc += phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
		if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
			adapter->stats.ecol += phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
		e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
		if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3802
			adapter->stats.mcc += phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
		e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
			adapter->stats.latecol += phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
		e1e_rphy(hw, HV_DC_UPPER, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
		if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
			adapter->stats.dc += phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
		adapter->stats.scc += er32(SCC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
		adapter->stats.ecol += er32(ECOL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
		adapter->stats.mcc += er32(MCC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
		adapter->stats.latecol += er32(LATECOL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		adapter->stats.dc += er32(DC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
	adapter->stats.xonrxc += er32(XONRXC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	adapter->stats.xontxc += er32(XONTXC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	adapter->stats.xoffrxc += er32(XOFFRXC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	adapter->stats.xofftxc += er32(XOFFTXC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	adapter->stats.gptc += er32(GPTC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
	adapter->stats.gotc += er32(GOTCL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
	er32(GOTCH); /* Clear gotc */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
	adapter->stats.rnbc += er32(RNBC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
	adapter->stats.ruc += er32(RUC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	adapter->stats.mptc += er32(MPTC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
	adapter->stats.bptc += er32(BPTC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	/* used for adaptive IFS */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
	hw->mac.tx_packet_delta = er32(TPT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	adapter->stats.tpt += hw->mac.tx_packet_delta;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	if ((hw->phy.type == e1000_phy_82578) ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	    (hw->phy.type == e1000_phy_82577)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
		e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
		if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
			hw->mac.collision_delta = phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
		hw->mac.collision_delta = er32(COLC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
	adapter->stats.colc += hw->mac.collision_delta;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	adapter->stats.algnerrc += er32(ALGNERRC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
	adapter->stats.rxerrc += er32(RXERRC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
	if ((hw->phy.type == e1000_phy_82578) ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
	    (hw->phy.type == e1000_phy_82577)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
		if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
			adapter->stats.tncrs += phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
		if ((hw->mac.type != e1000_82574) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		    (hw->mac.type != e1000_82583))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
			adapter->stats.tncrs += er32(TNCRS);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
	adapter->stats.cexterr += er32(CEXTERR);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
	adapter->stats.tsctc += er32(TSCTC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
	adapter->stats.tsctfc += er32(TSCTFC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
	/* Fill out the OS statistics structure */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
	netdev->stats.multicast = adapter->stats.mprc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	netdev->stats.collisions = adapter->stats.colc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	/* Rx Errors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
	 * RLEC on some newer hardware can be incorrect so build
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	 * our own version based on RUC and ROC
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	netdev->stats.rx_errors = adapter->stats.rxerrc +
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		adapter->stats.crcerrs + adapter->stats.algnerrc +
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
		adapter->stats.ruc + adapter->stats.roc +
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		adapter->stats.cexterr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
	netdev->stats.rx_length_errors = adapter->stats.ruc +
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
					      adapter->stats.roc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
	/* Tx Errors */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
	netdev->stats.tx_errors = adapter->stats.ecol +
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
				       adapter->stats.latecol;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
	netdev->stats.tx_window_errors = adapter->stats.latecol;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	/* Tx Dropped needs to be maintained elsewhere */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	/* Management Stats */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
	adapter->stats.mgptc += er32(MGTPTC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	adapter->stats.mgprc += er32(MGTPRC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	adapter->stats.mgpdc += er32(MGTPDC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
 * e1000_phy_read_status - Update the PHY register status snapshot
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
 * @adapter: board private structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
static void e1000_phy_read_status(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	struct e1000_phy_regs *phy = &adapter->phy_regs;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	int ret_val;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
	if ((er32(STATUS) & E1000_STATUS_LU) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
		ret_val  = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
		ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
		if (ret_val)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
			e_warn("Error reading PHY register\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
		 * Do not read PHY registers if link is not up
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
		 * Set values to typical power-on defaults
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
			     BMSR_ERCAP);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
				  ADVERTISE_ALL | ADVERTISE_CSMA);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
		phy->lpa = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		phy->expansion = EXPANSION_ENABLENPAGE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		phy->ctrl1000 = ADVERTISE_1000FULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
		phy->stat1000 = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
static void e1000_print_link_info(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
	u32 ctrl = er32(CTRL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
	/* Link status message must follow this format for user tools */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	printk(KERN_INFO "e1000e: %s NIC Link is Up %d Mbps %s, "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
	       "Flow Control: %s\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
	       adapter->netdev->name,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
	       adapter->link_speed,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
	       (adapter->link_duplex == FULL_DUPLEX) ?
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	                        "Full Duplex" : "Half Duplex",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
	       ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
	                        "RX/TX" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
	       ((ctrl & E1000_CTRL_RFCE) ? "RX" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
	       ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
bool e1000e_has_link(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
	bool link_active = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
	s32 ret_val = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
	 * get_link_status is set on LSC (link status) interrupt or
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
	 * Rx sequence error interrupt.  get_link_status will stay
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	 * false until the check_for_link establishes link
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	 * for copper adapters ONLY
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	switch (hw->phy.media_type) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
	case e1000_media_type_copper:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
		if (hw->mac.get_link_status) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
			ret_val = hw->mac.ops.check_for_link(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
			link_active = !hw->mac.get_link_status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
			link_active = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
	case e1000_media_type_fiber:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
		ret_val = hw->mac.ops.check_for_link(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
	case e1000_media_type_internal_serdes:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
		ret_val = hw->mac.ops.check_for_link(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
		link_active = adapter->hw.mac.serdes_has_link;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
	case e1000_media_type_unknown:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
		e_info("Gigabit has been disabled, downgrading speed\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	return link_active;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
static void e1000e_enable_receives(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
	/* make sure the receive unit is started */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
	    (adapter->flags & FLAG_RX_RESTART_NOW)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
		u32 rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
		ew32(RCTL, rctl | E1000_RCTL_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
		adapter->flags &= ~FLAG_RX_RESTART_NOW;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
 * e1000_watchdog - Timer Call-back
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
 * @data: pointer to adapter cast into an unsigned long
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
static void e1000_watchdog(unsigned long data)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
	/* Do the rest outside of interrupt context */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	schedule_work(&adapter->watchdog_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	/* TODO: make this use queue_delayed_work() */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
static void e1000_watchdog_task(struct work_struct *work)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
	struct e1000_adapter *adapter = container_of(work,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
					struct e1000_adapter, watchdog_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	struct e1000_mac_info *mac = &adapter->hw.mac;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
	struct e1000_phy_info *phy = &adapter->hw.phy;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
	u32 link, tctl;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
	int tx_pending = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
	link = e1000e_has_link(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	if ((adapter->ecdev && (ecdev_get_link(adapter->ecdev)) && link)
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  4038
			|| (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)) {
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
		/* Cancel scheduled suspend requests. */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
		pm_runtime_resume(netdev->dev.parent);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
		e1000e_enable_receives(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
		goto link_up;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
		e1000_update_mng_vlan(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	if (link) {
2421
bc2d4bf9cbe5 Removed trailing spaces.
Florian Pose <fp@igh-essen.com>
parents: 2290
diff changeset
  4051
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
			bool txb2b = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
			/* Cancel scheduled suspend requests. */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
			pm_runtime_resume(netdev->dev.parent);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
			/* update snapshot of PHY registers on LSC */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			e1000_phy_read_status(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
			mac->ops.get_link_up_info(&adapter->hw,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
						   &adapter->link_speed,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
						   &adapter->link_duplex);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
			e1000_print_link_info(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			 * On supported PHYs, check for duplex mismatch only
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
			 * if link has autonegotiated at 10/100 half
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
			if ((hw->phy.type == e1000_phy_igp_3 ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
			     hw->phy.type == e1000_phy_bm) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
			    (hw->mac.autoneg == true) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
			    (adapter->link_speed == SPEED_10 ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
			     adapter->link_speed == SPEED_100) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
			    (adapter->link_duplex == HALF_DUPLEX)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
				u16 autoneg_exp;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
				e1e_rphy(hw, PHY_AUTONEG_EXP, &autoneg_exp);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
				if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
					e_info("Autonegotiated half duplex but"
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
					       " link partner cannot autoneg. "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
					       " Try forcing full duplex if "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
					       "link gets many collisions.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
			/* adjust timeout factor according to speed/duplex */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
			adapter->tx_timeout_factor = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
			switch (adapter->link_speed) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
			case SPEED_10:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
				txb2b = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
				adapter->tx_timeout_factor = 16;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
				break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
			case SPEED_100:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
				txb2b = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
				adapter->tx_timeout_factor = 10;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
				break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
			 * workaround: re-program speed mode bit after
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
			 * link-up event
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
			    !txb2b) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
				u32 tarc0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
				tarc0 = er32(TARC(0));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
				tarc0 &= ~SPEED_MODE_BIT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
				ew32(TARC(0), tarc0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
			 * disable TSO for pcie and 10/100 speeds, to avoid
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
			 * some hardware issues
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
				switch (adapter->link_speed) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
				case SPEED_10:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
				case SPEED_100:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
					e_info("10/100 speed: disabling TSO\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
					netdev->features &= ~NETIF_F_TSO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
					netdev->features &= ~NETIF_F_TSO6;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
					break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
				case SPEED_1000:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
					netdev->features |= NETIF_F_TSO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
					netdev->features |= NETIF_F_TSO6;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
					break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
				default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
					/* oops */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
					break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
				}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
			 * enable transmits in the hardware, need to do this
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
			 * after setting TARC(0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
			tctl = er32(TCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
			tctl |= E1000_TCTL_EN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
			ew32(TCTL, tctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
                        /*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
			 * Perform any post-link-up configuration before
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
			 * reporting link up.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
			if (phy->ops.cfg_on_link_up)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
				phy->ops.cfg_on_link_up(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
			if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
				ecdev_set_link(adapter->ecdev, 1);
2421
bc2d4bf9cbe5 Removed trailing spaces.
Florian Pose <fp@igh-essen.com>
parents: 2290
diff changeset
  4149
			else
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
				netif_carrier_on(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
			if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
				mod_timer(&adapter->phy_info_timer,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
					  round_jiffies(jiffies + 2 * HZ));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	} else {
2421
bc2d4bf9cbe5 Removed trailing spaces.
Florian Pose <fp@igh-essen.com>
parents: 2290
diff changeset
  4157
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
			adapter->link_speed = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
			adapter->link_duplex = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
			/* Link status message must follow this format */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
			printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
			       adapter->netdev->name);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
			if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
				ecdev_set_link(adapter->ecdev, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
			else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
				netif_carrier_off(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
			if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
				mod_timer(&adapter->phy_info_timer,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
					  round_jiffies(jiffies + 2 * HZ));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
			if (adapter->flags & FLAG_RX_NEEDS_RESTART)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
				schedule_work(&adapter->reset_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
			else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
				pm_schedule_suspend(netdev->dev.parent,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
							LINK_TIMEOUT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
link_up:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
	e1000e_update_stats(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	adapter->tpt_old = adapter->stats.tpt;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
	adapter->colc_old = adapter->stats.colc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	adapter->gorc_old = adapter->stats.gorc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	adapter->gotc_old = adapter->stats.gotc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	e1000e_update_adaptive(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
2500
97fd83907c7c Fixed repeating e1000e reset while link down, thanks to J. Kunz.
Florian Pose <fp@igh-essen.com>
parents: 2473
diff changeset
  4195
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		tx_pending = (e1000_desc_unused(tx_ring) + 1 <
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
			       tx_ring->count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		if (tx_pending) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
			/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
			 * We've lost link, so the controller stops DMA,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
			 * but we've got queued Tx work that's never going
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
			 * to get done, so reset controller to flush Tx.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
			 * (Do the reset outside of interrupt context).
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
			 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
			adapter->tx_timeout_count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
			schedule_work(&adapter->reset_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
			/* return immediately since reset is imminent */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
			return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
	/* Simple mode for Interrupt Throttle Rate (ITR) */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
	if (adapter->itr_setting == 4) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
		 * Symmetric Tx/Rx gets a reduced ITR=2000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
		 * Total asymmetrical Tx or Rx gets ITR=8000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
		 * everyone else is between 2000-8000.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
		u32 goc = (adapter->gotc + adapter->gorc) / 10000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
		u32 dif = (adapter->gotc > adapter->gorc ?
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
			    adapter->gotc - adapter->gorc :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
			    adapter->gorc - adapter->gotc) / 10000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
		u32 itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
		ew32(ITR, 1000000000 / (itr * 256));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	/* Cause software interrupt to ensure Rx ring is cleaned */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
	if (adapter->msix_entries)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
		ew32(ICS, adapter->rx_ring->ims_val);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
		ew32(ICS, E1000_ICS_RXDMT0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	/* Force detection of hung controller every watchdog period */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
	adapter->detect_tx_hung = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
	 * With 82571 controllers, LAA may be overwritten due to controller
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
	 * reset from the other port. Set the appropriate LAA in RAR[0]
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
	if (e1000e_get_laa_state_82571(hw))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
		e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	/* Reset the timer */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
	if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
		mod_timer(&adapter->watchdog_timer,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
			  round_jiffies(jiffies + 2 * HZ));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
#define E1000_TX_FLAGS_CSUM		0x00000001
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
#define E1000_TX_FLAGS_VLAN		0x00000002
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
#define E1000_TX_FLAGS_TSO		0x00000004
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
#define E1000_TX_FLAGS_IPV4		0x00000008
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
#define E1000_TX_FLAGS_VLAN_SHIFT	16
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
static int e1000_tso(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
		     struct sk_buff *skb)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
	struct e1000_context_desc *context_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
	u32 cmd_length = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	u16 ipcse = 0, tucse, mss;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	int err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
	if (!skb_is_gso(skb))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
	if (skb_header_cloned(skb)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
		if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
			return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	mss = skb_shinfo(skb)->gso_size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	if (skb->protocol == htons(ETH_P_IP)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
		struct iphdr *iph = ip_hdr(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
		iph->tot_len = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
		iph->check = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
		                                         0, IPPROTO_TCP, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
		cmd_length = E1000_TXD_CMD_IP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
		ipcse = skb_transport_offset(skb) - 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	} else if (skb_is_gso_v6(skb)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		ipv6_hdr(skb)->payload_len = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
		                                       &ipv6_hdr(skb)->daddr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
		                                       0, IPPROTO_TCP, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
		ipcse = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	ipcss = skb_network_offset(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
	tucss = skb_transport_offset(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
	tucse = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
	               E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
	i = tx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
	buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
	context_desc->lower_setup.ip_fields.ipcss  = ipcss;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	context_desc->lower_setup.ip_fields.ipcso  = ipcso;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	context_desc->upper_setup.tcp_fields.tucss = tucss;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
	context_desc->upper_setup.tcp_fields.tucso = tucso;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
	context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	buffer_info->time_stamp = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
	buffer_info->next_to_watch = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
	i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
	if (i == tx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
		i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
	tx_ring->next_to_use = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
	return 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
	struct e1000_context_desc *context_desc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
	u8 css;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
	u32 cmd_len = E1000_TXD_CMD_DEXT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
	__be16 protocol;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
	if (skb->ip_summed != CHECKSUM_PARTIAL)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
		protocol = skb->protocol;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
	switch (protocol) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
	case cpu_to_be16(ETH_P_IP):
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
			cmd_len |= E1000_TXD_CMD_TCP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	case cpu_to_be16(ETH_P_IPV6):
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
		/* XXX not handling all IPV6 headers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
			cmd_len |= E1000_TXD_CMD_TCP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
		if (unlikely(net_ratelimit()))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
			e_warn("checksum_partial proto=%x!\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
			       be16_to_cpu(protocol));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
	css = skb_transport_offset(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
	i = tx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
	buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
	context_desc->lower_setup.ip_config = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
	context_desc->upper_setup.tcp_fields.tucss = css;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
	context_desc->upper_setup.tcp_fields.tucso =
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
				css + skb->csum_offset;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
	context_desc->upper_setup.tcp_fields.tucse = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
	context_desc->tcp_seg_setup.data = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	buffer_info->time_stamp = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
	buffer_info->next_to_watch = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
	i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
	if (i == tx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
		i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
	tx_ring->next_to_use = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
	return 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
#define E1000_MAX_PER_TXD	8192
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
#define E1000_MAX_TXD_PWR	12
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
static int e1000_tx_map(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			struct sk_buff *skb, unsigned int first,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
			unsigned int max_per_txd, unsigned int nr_frags,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
			unsigned int mss)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
	struct pci_dev *pdev = adapter->pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	unsigned int len = skb_headlen(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	unsigned int offset = 0, size, count = 0, i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
	unsigned int f, bytecount, segs;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	i = tx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
	while (len) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
		size = min(len, max_per_txd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
		buffer_info->length = size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
		buffer_info->time_stamp = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
		buffer_info->next_to_watch = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
		buffer_info->dma = dma_map_single(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
						  skb->data + offset,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
						  size,	DMA_TO_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
		buffer_info->mapped_as_page = false;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		if (dma_mapping_error(&pdev->dev, buffer_info->dma))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
			goto dma_error;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
		len -= size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
		offset += size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
		count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
		if (len) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
			i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
			if (i == tx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
				i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
	for (f = 0; f < nr_frags; f++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
		struct skb_frag_struct *frag;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
		frag = &skb_shinfo(skb)->frags[f];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
		len = frag->size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		offset = frag->page_offset;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
		while (len) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
			i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
			if (i == tx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
				i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
			buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
			size = min(len, max_per_txd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
			buffer_info->length = size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
			buffer_info->time_stamp = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
			buffer_info->next_to_watch = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
			buffer_info->dma = dma_map_page(&pdev->dev, frag->page,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
							offset, size,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
							DMA_TO_DEVICE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
			buffer_info->mapped_as_page = true;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
			if (dma_mapping_error(&pdev->dev, buffer_info->dma))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
				goto dma_error;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
			len -= size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
			offset += size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
			count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	segs = skb_shinfo(skb)->gso_segs ?: 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	/* multiply data chunks by size of headers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	bytecount = ((segs - 1) * skb_headlen(skb)) + skb->len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	tx_ring->buffer_info[i].skb = skb;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
	tx_ring->buffer_info[i].segs = segs;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	tx_ring->buffer_info[i].bytecount = bytecount;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
	tx_ring->buffer_info[first].next_to_watch = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	return count;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
dma_error:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
	dev_err(&pdev->dev, "TX DMA map failed\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
	buffer_info->dma = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
	if (count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
		count--;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
	while (count--) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
		if (i==0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
			i += tx_ring->count;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
		i--;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
		buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		e1000_put_txbuf(adapter, buffer_info);;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
static void e1000_tx_queue(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
			   int tx_flags, int count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
	struct e1000_tx_desc *tx_desc = NULL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
	struct e1000_buffer *buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	unsigned int i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
	if (tx_flags & E1000_TX_FLAGS_TSO) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
			     E1000_TXD_CMD_TSE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
		if (tx_flags & E1000_TX_FLAGS_IPV4)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
		txd_lower |= E1000_TXD_CMD_VLE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
	i = tx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
	while (count--) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		buffer_info = &tx_ring->buffer_info[i];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
		tx_desc = E1000_TX_DESC(*tx_ring, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
		tx_desc->lower.data =
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			cpu_to_le32(txd_lower | buffer_info->length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
		tx_desc->upper.data = cpu_to_le32(txd_upper);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		i++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		if (i == tx_ring->count)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
			i = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	 * Force memory writes to complete before letting h/w
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	 * know there are new descriptors to fetch.  (Only
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
	 * applicable for weak-ordered memory model archs,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
	 * such as IA-64).
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	wmb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
	tx_ring->next_to_use = i;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	writel(i, adapter->hw.hw_addr + tx_ring->tail);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	 * we need this if more than one processor can write to our tail
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
	 * at a time, it synchronizes IO on IA64/Altix systems
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
	mmiowb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
#define MINIMUM_DHCP_PACKET_SIZE 282
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
				    struct sk_buff *skb)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	struct e1000_hw *hw =  &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
	u16 length, offset;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	if (vlan_tx_tag_present(skb)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
		    (adapter->hw.mng_cookie.status &
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
			return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
		const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
		struct udphdr *udp;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
		if (ip->protocol != IPPROTO_UDP)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
			return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
		if (ntohs(udp->dest) != 67)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
			return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
		offset = (u8 *)udp + 8 - skb->data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
		length = skb->len - offset;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
		return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
2472
50b861e981f7 Fixed __e1000_maybe_stop_tx() for e1000e.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  4595
	if (adapter->ecdev) {
50b861e981f7 Fixed __e1000_maybe_stop_tx() for e1000e.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  4596
		return -EBUSY;
50b861e981f7 Fixed __e1000_maybe_stop_tx() for e1000e.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  4597
	}
50b861e981f7 Fixed __e1000_maybe_stop_tx() for e1000e.
Florian Pose <fp@igh-essen.com>
parents: 2421
diff changeset
  4598
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	netif_stop_queue(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	 * Herbert's original patch had:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
	 *  smp_mb__after_netif_stop_queue();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	 * but since that doesn't exist yet, just open code it.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	smp_mb();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	 * We need to check again in a case another CPU has just
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	 * made room available.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
	if (e1000_desc_unused(adapter->tx_ring) < size)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
		return -EBUSY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	/* A reprieve! */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
	netif_start_queue(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	++adapter->restart_queue;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
static int e1000_maybe_stop_tx(struct net_device *netdev, int size)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
	if (e1000_desc_unused(adapter->tx_ring) >= size)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
	return __e1000_maybe_stop_tx(netdev, size);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
				    struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
	struct e1000_ring *tx_ring = adapter->tx_ring;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
	unsigned int first;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
	unsigned int max_per_txd = E1000_MAX_PER_TXD;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
	unsigned int tx_flags = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	unsigned int len = skb_headlen(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
	unsigned int nr_frags;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
	unsigned int mss;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
	int count = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
	int tso;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
	unsigned int f;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	if (test_bit(__E1000_DOWN, &adapter->state)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
		if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
			dev_kfree_skb_any(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
		return NETDEV_TX_OK;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
	if (skb->len <= 0) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
		if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
			dev_kfree_skb_any(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
		return NETDEV_TX_OK;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
	mss = skb_shinfo(skb)->gso_size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	 * The controller does a simple calculation to
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
	 * make sure there is enough room in the FIFO before
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
	 * initiating the DMA for each buffer.  The calc is:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	 * 4 = ceil(buffer len/mss).  To make sure we don't
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
	 * overrun the FIFO, adjust the max buffer len if mss
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
	 * drops.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
	if (mss) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
		u8 hdr_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
		max_per_txd = min(mss << 2, max_per_txd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
		max_txd_pwr = fls(max_per_txd) - 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
		 * TSO Workaround for 82571/2/3 Controllers -- if skb->data
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
		 * points to just header, pull a few bytes of payload from
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
		 * frags into skb->data
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
		/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
		 * we do this workaround for ES2LAN, but it is un-necessary,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
		 * avoiding it could save a lot of cycles
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
		 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
		if (skb->data_len && (hdr_len == len)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
			unsigned int pull_size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
			pull_size = min((unsigned int)4, skb->data_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
			if (!__pskb_pull_tail(skb, pull_size)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
				e_err("__pskb_pull_tail failed.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
				if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
					dev_kfree_skb_any(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
				return NETDEV_TX_OK;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
			len = skb_headlen(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
	/* reserve a descriptor for the offload context */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
		count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
	count += TXD_USE_COUNT(len, max_txd_pwr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
	nr_frags = skb_shinfo(skb)->nr_frags;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
	for (f = 0; f < nr_frags; f++)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
				       max_txd_pwr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
	if (adapter->hw.mac.tx_pkt_filtering)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
		e1000_transfer_dhcp_info(adapter, skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	 * need: count + 2 desc gap to keep tail from touching
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	 * head, otherwise try next time
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	if (!adapter->ecdev && e1000_maybe_stop_tx(netdev, count + 2))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		return NETDEV_TX_BUSY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
		tx_flags |= E1000_TX_FLAGS_VLAN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
	first = tx_ring->next_to_use;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
	tso = e1000_tso(adapter, skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
	if (tso < 0) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
		if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
			dev_kfree_skb_any(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
		return NETDEV_TX_OK;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
	if (tso)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
		tx_flags |= E1000_TX_FLAGS_TSO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	else if (e1000_tx_csum(adapter, skb))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
		tx_flags |= E1000_TX_FLAGS_CSUM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	 * Old method was to assume IPv4 packet by default if TSO was enabled.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	 * no longer assume, we must.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	if (skb->protocol == htons(ETH_P_IP))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
		tx_flags |= E1000_TX_FLAGS_IPV4;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	/* if count is 0 then mapping error has occured */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	if (count) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
		e1000_tx_queue(adapter, tx_flags, count);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
		/* Make sure there is space in the ring for the next send. */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
		if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
			e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
		if (!adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
			dev_kfree_skb_any(skb);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
		tx_ring->buffer_info[first].time_stamp = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
		tx_ring->next_to_use = first;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
	return NETDEV_TX_OK;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
 * e1000_tx_timeout - Respond to a Tx Hang
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
 * @netdev: network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
static void e1000_tx_timeout(struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
	/* Do the reset outside of interrupt context */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	adapter->tx_timeout_count++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	schedule_work(&adapter->reset_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
static void e1000_reset_task(struct work_struct *work)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
	struct e1000_adapter *adapter;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	adapter = container_of(work, struct e1000_adapter, reset_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	e1000e_dump(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
	e_err("Reset adapter\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	e1000e_reinit_locked(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
 * e1000_get_stats - Get System Network Statistics
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
 * @netdev: network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
 * Returns the address of the device statistics structure.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
 * The statistics are actually updated from the timer callback.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
	/* only return the current stats */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	return &netdev->stats;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
 * e1000_change_mtu - Change the Maximum Transfer Unit
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
 * @netdev: network interface device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
 * @new_mtu: new value for maximum frame size
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
 * Returns 0 on success, negative on failure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
		return -EBUSY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
	/* Jumbo frame support */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
		e_err("Jumbo Frames not supported.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
		return -EINVAL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
	/* Supported frame sizes */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	    (max_frame > adapter->max_hw_frame_size)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
		e_err("Unsupported MTU setting\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
		return -EINVAL;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
	/* 82573 Errata 17 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
	if (((adapter->hw.mac.type == e1000_82573) ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
	     (adapter->hw.mac.type == e1000_82574)) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
	    (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
		adapter->flags2 |= FLAG2_DISABLE_ASPM_L1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
		e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		msleep(1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	adapter->max_frame_size = max_frame;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
	netdev->mtu = new_mtu;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	if (netif_running(netdev))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
		e1000e_down(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
	 * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
	 * means we reserve 2 more, this pushes us to allocate from the next
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
	 * larger slab size.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
	 * i.e. RXBUFFER_2048 --> size-4096 slab
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	 * However with the new *_jumbo_rx* routines, jumbo receives will use
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	 * fragmented skbs
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	if (max_frame <= 2048)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
		adapter->rx_buffer_len = 2048;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
		adapter->rx_buffer_len = 4096;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
	/* adjust allocation if LPE protects us, and we aren't using SBP */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
	     (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
					 + ETH_FCS_LEN;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	if (netif_running(netdev))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
		e1000e_up(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
	else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
		e1000e_reset(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
	clear_bit(__E1000_RESETTING, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
			   int cmd)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
	struct mii_ioctl_data *data = if_mii(ifr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
	if (adapter->hw.phy.media_type != e1000_media_type_copper)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
		return -EOPNOTSUPP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	switch (cmd) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
	case SIOCGMIIPHY:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
		data->phy_id = adapter->hw.phy.addr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
	case SIOCGMIIREG:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
		e1000_phy_read_status(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
		switch (data->reg_num & 0x1F) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
		case MII_BMCR:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
			data->val_out = adapter->phy_regs.bmcr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
		case MII_BMSR:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
			data->val_out = adapter->phy_regs.bmsr;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
		case MII_PHYSID1:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
			data->val_out = (adapter->hw.phy.id >> 16);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
		case MII_PHYSID2:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
			data->val_out = (adapter->hw.phy.id & 0xFFFF);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
		case MII_ADVERTISE:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
			data->val_out = adapter->phy_regs.advertise;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
		case MII_LPA:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
			data->val_out = adapter->phy_regs.lpa;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
		case MII_EXPANSION:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
			data->val_out = adapter->phy_regs.expansion;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
		case MII_CTRL1000:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
			data->val_out = adapter->phy_regs.ctrl1000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
		case MII_STAT1000:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
			data->val_out = adapter->phy_regs.stat1000;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
		case MII_ESTATUS:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
			data->val_out = adapter->phy_regs.estatus;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
		default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
			return -EIO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
		break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
	case SIOCSMIIREG:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
		return -EOPNOTSUPP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
	switch (cmd) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	case SIOCGMIIPHY:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	case SIOCGMIIREG:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	case SIOCSMIIREG:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
		return e1000_mii_ioctl(netdev, ifr, cmd);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
	default:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		return -EOPNOTSUPP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
	u32 i, mac_reg;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
	u16 phy_reg;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
	int retval = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
	/* copy MAC RARs to PHY RARs */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
	for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
		mac_reg = er32(RAL(i));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
		e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
		e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
		mac_reg = er32(RAH(i));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
		e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
		e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
	/* copy MAC MTA to PHY MTA */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
		mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
		e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
		e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
	/* configure PHY Rx Control register */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
	e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
	mac_reg = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
	if (mac_reg & E1000_RCTL_UPE)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
		phy_reg |= BM_RCTL_UPE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
	if (mac_reg & E1000_RCTL_MPE)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
		phy_reg |= BM_RCTL_MPE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
	phy_reg &= ~(BM_RCTL_MO_MASK);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
	if (mac_reg & E1000_RCTL_MO_3)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
		phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
				<< BM_RCTL_MO_SHIFT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
	if (mac_reg & E1000_RCTL_BAM)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
		phy_reg |= BM_RCTL_BAM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	if (mac_reg & E1000_RCTL_PMCF)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
		phy_reg |= BM_RCTL_PMCF;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
	mac_reg = er32(CTRL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
	if (mac_reg & E1000_CTRL_RFCE)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
		phy_reg |= BM_RCTL_RFCE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
	e1e_wphy(&adapter->hw, BM_RCTL, phy_reg);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
	/* enable PHY wakeup in MAC register */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
	ew32(WUFC, wufc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
	ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
	/* configure and enable PHY wakeup in PHY registers */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
	e1e_wphy(&adapter->hw, BM_WUFC, wufc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
	e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	/* activate PHY wakeup */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
	retval = hw->phy.ops.acquire(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	if (retval) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
		e_err("Could not acquire PHY\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
		return retval;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
	                         (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
	retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
	if (retval) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
		e_err("Could not read PHY page 769\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
		goto out;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
	retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	if (retval)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		e_err("Could not set PHY Host Wakeup bit\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
out:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
	hw->phy.ops.release(hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
	return retval;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
			    bool runtime)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
	u32 ctrl, ctrl_ext, rctl, status;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
	/* Runtime suspend should only enable wakeup for link changes */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
	u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
	int retval = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
	netif_device_detach(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
	if (netif_running(netdev)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
		e1000e_down(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
		e1000_free_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
	e1000e_reset_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	retval = pci_save_state(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
	if (retval)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
		return retval;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	status = er32(STATUS);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	if (status & E1000_STATUS_LU)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
		wufc &= ~E1000_WUFC_LNKC;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	if (wufc) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
		e1000_setup_rctl(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
		e1000_set_multi(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
		/* turn on all-multi mode if wake on multicast is enabled */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
		if (wufc & E1000_WUFC_MC) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
			rctl = er32(RCTL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
			rctl |= E1000_RCTL_MPE;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
			ew32(RCTL, rctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
		ctrl = er32(CTRL);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
		/* advertise wake from D3Cold */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
		#define E1000_CTRL_ADVD3WUC 0x00100000
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
		/* phy power management enable */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
		#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
		ctrl |= E1000_CTRL_ADVD3WUC;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
		ew32(CTRL, ctrl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
		    adapter->hw.phy.media_type ==
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
		    e1000_media_type_internal_serdes) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
			/* keep the laser running in D3 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
			ctrl_ext = er32(CTRL_EXT);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
			ew32(CTRL_EXT, ctrl_ext);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
		if (adapter->flags & FLAG_IS_ICH)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
			e1000e_disable_gig_wol_ich8lan(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
		/* Allow time for pending master requests to run */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
		e1000e_disable_pcie_master(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
			/* enable wakeup by the PHY */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
			retval = e1000_init_phy_wakeup(adapter, wufc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
			if (retval)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
				return retval;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
		} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
			/* enable wakeup by the MAC */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
			ew32(WUFC, wufc);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
			ew32(WUC, E1000_WUC_PME_EN);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
		ew32(WUC, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
		ew32(WUFC, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
	*enable_wake = !!wufc;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
	/* make sure adapter isn't asleep if manageability is enabled */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
	if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
	    (hw->mac.ops.check_mng_mode(hw)))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
		*enable_wake = true;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	if (adapter->hw.phy.type == e1000_phy_igp_3)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	 * would have already happened in close and is redundant.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
	e1000_release_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
	pci_disable_device(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
	if (sleep && wake) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
		pci_prepare_to_sleep(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	pci_wake_from_d3(pdev, wake);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
	pci_set_power_state(pdev, PCI_D3hot);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
                                    bool wake)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
	 * The pci-e switch on some quad port adapters will report a
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
	 * correctable error when the MAC transitions from D0 to D3.  To
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
	 * prevent this we need to mask off the correctable errors on the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
	 * downstream port of the pci-e switch.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
		struct pci_dev *us_dev = pdev->bus->self;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
		int pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
		u16 devctl;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
		pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
		                      (devctl & ~PCI_EXP_DEVCTL_CERE));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
		e1000_power_off(pdev, sleep, wake);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
		e1000_power_off(pdev, sleep, wake);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
#ifdef CONFIG_PCIEASPM
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
	pci_disable_link_state(pdev, state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
#else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
	int pos;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	u16 reg16;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
	 * Both device and parent should have the same ASPM setting.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	 * Disable ASPM in downstream component first and then upstream.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
	pos = pci_pcie_cap(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &reg16);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
	reg16 &= ~state;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
	pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
	if (!pdev->bus->self)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
	pos = pci_pcie_cap(pdev->bus->self);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
	pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, &reg16);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
	reg16 &= ~state;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
#endif
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
	dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
		 (state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
		 (state & PCIE_LINK_STATE_L1) ? "L1" : "");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
	__e1000e_disable_aspm(pdev, state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
#ifdef CONFIG_PM_OPS
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
static bool e1000e_pm_ready(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	return !!adapter->tx_ring->buffer_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
static int __e1000_resume(struct pci_dev *pdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
	u32 err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
		return -EBUSY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
	pci_set_power_state(pdev, PCI_D0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
	pci_restore_state(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	pci_save_state(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
	e1000e_set_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
	if (netif_running(netdev)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
		err = e1000_request_irq(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
		if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
			return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
	e1000e_power_up_phy(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	/* report the system wakeup cause from S3/S4 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
		u16 phy_data;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
		e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
		if (phy_data) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
			e_info("PHY Wakeup cause - %s\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
				phy_data & E1000_WUS_EX ? "Unicast Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
				phy_data & E1000_WUS_MC ? "Multicast Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
				phy_data & E1000_WUS_BC ? "Broadcast Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
				phy_data & E1000_WUS_MAG ? "Magic Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
				phy_data & E1000_WUS_LNKC ? "Link Status "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
				" Change" : "other");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
		u32 wus = er32(WUS);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
		if (wus) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
			e_info("MAC Wakeup cause - %s\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
				wus & E1000_WUS_EX ? "Unicast Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
				wus & E1000_WUS_MC ? "Multicast Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
				wus & E1000_WUS_BC ? "Broadcast Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
				wus & E1000_WUS_MAG ? "Magic Packet" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
				wus & E1000_WUS_LNKC ? "Link Status Change" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
				"other");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
		ew32(WUS, ~0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	e1000e_reset(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
	e1000_init_manageability_pt(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	if (netif_running(netdev))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
		e1000e_up(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
	netif_device_attach(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
	 * If the controller has AMT, do not set DRV_LOAD until the interface
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
	 * is up.  For all other cases, let the f/w know that the h/w is now
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
	 * under the control of the driver.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
	if (!(adapter->flags & FLAG_HAS_AMT))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
		e1000_get_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
#ifdef CONFIG_PM_SLEEP
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
static int e1000_suspend(struct device *dev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
	struct pci_dev *pdev = to_pci_dev(dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
	int retval;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
	bool wake;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  5287
	if (adapter->ecdev) {
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  5288
		return -EBUSY;
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  5289
	}
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	retval = __e1000_shutdown(pdev, &wake, false);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	if (!retval)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
		e1000_complete_shutdown(pdev, true, wake);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
	return retval;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
static int e1000_resume(struct device *dev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
	struct pci_dev *pdev = to_pci_dev(dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
2473
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  5304
	if (adapter->ecdev) {
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  5305
		return -EBUSY;
f62b64fdbc23 Fixed e1000_open() in e1000e drivers.
Florian Pose <fp@igh-essen.com>
parents: 2472
diff changeset
  5306
	}
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
	if (e1000e_pm_ready(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
		adapter->idle_check = true;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
	return __e1000_resume(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
#endif /* CONFIG_PM_SLEEP */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
#ifdef CONFIG_PM_RUNTIME
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
static int e1000_runtime_suspend(struct device *dev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	struct pci_dev *pdev = to_pci_dev(dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
	if (e1000e_pm_ready(adapter)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
		bool wake;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
		__e1000_shutdown(pdev, &wake, true);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
static int e1000_idle(struct device *dev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
	struct pci_dev *pdev = to_pci_dev(dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
	if (!e1000e_pm_ready(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
	if (adapter->idle_check) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
		adapter->idle_check = false;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
		if (!e1000e_has_link(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
			pm_schedule_suspend(dev, MSEC_PER_SEC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
	return -EBUSY;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
static int e1000_runtime_resume(struct device *dev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
	struct pci_dev *pdev = to_pci_dev(dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
	if (!e1000e_pm_ready(adapter))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
		return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
	adapter->idle_check = !dev->power.runtime_auto;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	return __e1000_resume(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
#endif /* CONFIG_PM_RUNTIME */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
#endif /* CONFIG_PM_OPS */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
static void e1000_shutdown(struct pci_dev *pdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	bool wake = false;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5367
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5368
	struct e1000_adapter *adapter = netdev_priv(netdev);
2421
bc2d4bf9cbe5 Removed trailing spaces.
Florian Pose <fp@igh-essen.com>
parents: 2290
diff changeset
  5369
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
	if (adapter->ecdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
	__e1000_shutdown(pdev, &wake, false);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
	if (system_state == SYSTEM_POWER_OFF)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
		e1000_complete_shutdown(pdev, false, wake);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
#ifdef CONFIG_NET_POLL_CONTROLLER
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
 * Polling 'interrupt' - used by things like netconsole to send skbs
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
 * without having to re-enable interrupts. It's not called while
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
 * the interrupt routine is executing.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
static void e1000_netpoll(struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
	disable_irq(adapter->pdev->irq);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
	e1000_intr(adapter->pdev->irq, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
	enable_irq(adapter->pdev->irq);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
#endif
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
 * e1000_io_error_detected - called when PCI error is detected
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
 * @pdev: Pointer to PCI device
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
 * @state: The current pci connection state
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
 * This function is called after a PCI bus error affecting
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
 * this device has been detected.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
						pci_channel_state_t state)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
	netif_device_detach(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
	if (state == pci_channel_io_perm_failure)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
		return PCI_ERS_RESULT_DISCONNECT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
	if (netif_running(netdev))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
		e1000e_down(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
	pci_disable_device(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
	/* Request a slot slot reset. */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
	return PCI_ERS_RESULT_NEED_RESET;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
 * e1000_io_slot_reset - called after the pci bus has been reset.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
 * @pdev: Pointer to PCI device
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
 * Restart the card from scratch, as if from a cold-boot. Implementation
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
 * resembles the first-half of the e1000_resume routine.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
	int err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
	pci_ers_result_t result;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	err = pci_enable_device_mem(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	if (err) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
		dev_err(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
			"Cannot re-enable PCI device after reset.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
		result = PCI_ERS_RESULT_DISCONNECT;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
		pci_set_master(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
		pdev->state_saved = true;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
		pci_restore_state(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
		pci_enable_wake(pdev, PCI_D3hot, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
		pci_enable_wake(pdev, PCI_D3cold, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
		e1000e_reset(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
		ew32(WUS, ~0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
		result = PCI_ERS_RESULT_RECOVERED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
	pci_cleanup_aer_uncorrect_error_status(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
	return result;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
 * e1000_io_resume - called when traffic can start flowing again.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
 * @pdev: Pointer to PCI device
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
 * This callback is called when the error recovery driver tells us that
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
 * its OK to resume normal operation. Implementation resembles the
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
 * second-half of the e1000_resume routine.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
static void e1000_io_resume(struct pci_dev *pdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
	e1000_init_manageability_pt(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
	if (netif_running(netdev)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
		if (e1000e_up(adapter)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
			dev_err(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
				"can't bring device back up after reset\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
			return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
	netif_device_attach(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
	 * If the controller has AMT, do not set DRV_LOAD until the interface
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
	 * is up.  For all other cases, let the f/w know that the h/w is now
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
	 * under the control of the driver.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
	if (!(adapter->flags & FLAG_HAS_AMT))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
		e1000_get_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
static void e1000_print_device_info(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
	struct net_device *netdev = adapter->netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
	u32 pba_num;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
	/* print bus type/speed/width info */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
	e_info("(PCI Express:2.5GB/s:%s) %pM\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
	       /* bus width */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
	        "Width x1"),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
	       /* MAC address */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
	       netdev->dev_addr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
	e_info("Intel(R) PRO/%s Network Connection\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
	e1000e_read_pba_num(hw, &pba_num);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
	e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
	       hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
	struct e1000_hw *hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
	int ret_val;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	u16 buf = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
	if (hw->mac.type != e1000_82573)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
		return;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
	if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
		/* Deep Smart Power Down (DSPD) */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
		dev_warn(&adapter->pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
			 "Warning: detected DSPD enabled in EEPROM\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
static const struct net_device_ops e1000e_netdev_ops = {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
	.ndo_open		= e1000_open,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
	.ndo_stop		= e1000_close,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
	.ndo_start_xmit		= e1000_xmit_frame,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
	.ndo_get_stats		= e1000_get_stats,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	.ndo_set_multicast_list	= e1000_set_multi,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
	.ndo_set_mac_address	= e1000_set_mac,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
	.ndo_change_mtu		= e1000_change_mtu,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
	.ndo_do_ioctl		= e1000_ioctl,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
	.ndo_tx_timeout		= e1000_tx_timeout,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
	.ndo_validate_addr	= eth_validate_addr,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
#ifdef CONFIG_NET_POLL_CONTROLLER
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
	.ndo_poll_controller	= e1000_netpoll,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
#endif
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
 * ec_poll - Ethercat poll Routine
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
 * @netdev: net device structure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
 * This function can never fail.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
void ec_poll(struct net_device *netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
	if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
		e1000_watchdog((unsigned long) adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
		adapter->ec_watchdog_jiffies = jiffies;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
#ifdef CONFIG_PCI_MSI
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
	e1000_intr_msi(0,netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
#else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
	e1000_intr(0,netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
#endif
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
 * e1000_probe - Device Initialization Routine
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
 * @pdev: PCI device information struct
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
 * @ent: entry in e1000_pci_tbl
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
 * Returns 0 on success, negative on failure
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
 * e1000_probe initializes an adapter identified by a pci_dev structure.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
 * The OS initialization, configuring of the adapter private structure,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
 * and a hardware reset occur.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
static int __devinit e1000_probe(struct pci_dev *pdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
				 const struct pci_device_id *ent)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
	struct net_device *netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
	struct e1000_adapter *adapter;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
	struct e1000_hw *hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
	resource_size_t mmio_start, mmio_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
	resource_size_t flash_start, flash_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
	static int cards_found;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
	int i, err, pci_using_dac;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
	u16 eeprom_data = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5604
	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5605
		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5606
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5607
	err = pci_enable_device_mem(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5608
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5609
		return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5610
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5611
	pci_using_dac = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5612
	err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5613
	if (!err) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5614
		err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5615
		if (!err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5616
			pci_using_dac = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5617
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5618
		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5619
		if (err) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5620
			err = dma_set_coherent_mask(&pdev->dev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5621
						    DMA_BIT_MASK(32));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5622
			if (err) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5623
				dev_err(&pdev->dev, "No usable DMA "
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5624
					"configuration, aborting\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5625
				goto err_dma;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5626
			}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5627
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5628
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5629
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5630
	err = pci_request_selected_regions_exclusive(pdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5631
	                                  pci_select_bars(pdev, IORESOURCE_MEM),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5632
	                                  e1000e_driver_name);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5633
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5634
		goto err_pci_reg;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5635
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5636
	/* AER (Advanced Error Reporting) hooks */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5637
	pci_enable_pcie_error_reporting(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5638
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5639
	pci_set_master(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5640
	/* PCI config space info */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5641
	err = pci_save_state(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5642
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5643
		goto err_alloc_etherdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5644
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5645
	err = -ENOMEM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5646
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5647
	if (!netdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5648
		goto err_alloc_etherdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5649
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5650
	SET_NETDEV_DEV(netdev, &pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5651
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5652
	netdev->irq = pdev->irq;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5653
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5654
	pci_set_drvdata(pdev, netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5655
	adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5656
	hw = &adapter->hw;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5657
	adapter->netdev = netdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5658
	adapter->pdev = pdev;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5659
	adapter->ei = ei;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5660
	adapter->pba = ei->pba;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5661
	adapter->flags = ei->flags;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5662
	adapter->flags2 = ei->flags2;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5663
	adapter->hw.adapter = adapter;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5664
	adapter->hw.mac.type = ei->mac;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5665
	adapter->max_hw_frame_size = ei->max_hw_frame_size;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5666
	adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5667
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5668
	mmio_start = pci_resource_start(pdev, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5669
	mmio_len = pci_resource_len(pdev, 0);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5670
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5671
	err = -EIO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5672
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5673
	if (!adapter->hw.hw_addr)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5674
		goto err_ioremap;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5675
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5676
	if ((adapter->flags & FLAG_HAS_FLASH) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5677
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5678
		flash_start = pci_resource_start(pdev, 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5679
		flash_len = pci_resource_len(pdev, 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5680
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5681
		if (!adapter->hw.flash_address)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5682
			goto err_flashmap;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5683
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5684
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5685
	/* construct the net_device struct */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5686
	netdev->netdev_ops		= &e1000e_netdev_ops;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5687
	e1000e_set_ethtool_ops(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5688
	netdev->watchdog_timeo		= 5 * HZ;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5689
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5690
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5691
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5692
	netdev->mem_start = mmio_start;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5693
	netdev->mem_end = mmio_start + mmio_len;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5694
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5695
	adapter->bd_number = cards_found++;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5696
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5697
	e1000e_check_options(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5698
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5699
	/* setup adapter struct */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5700
	err = e1000_sw_init(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5701
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5702
		goto err_sw_init;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5703
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5704
	err = -EIO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5705
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5706
	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5707
	memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5708
	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5709
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5710
	err = ei->get_variants(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5711
	if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5712
		goto err_hw_init;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5713
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5714
	if ((adapter->flags & FLAG_IS_ICH) &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5715
	    (adapter->flags & FLAG_READ_ONLY_NVM))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5716
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5717
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5718
	hw->mac.ops.get_bus_info(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5719
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5720
	adapter->hw.phy.autoneg_wait_to_complete = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5721
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5722
	/* Copper options */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5723
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5724
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5725
		adapter->hw.phy.disable_polarity_correction = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5726
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5727
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5728
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5729
	if (e1000_check_reset_block(&adapter->hw))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5730
		e_info("PHY reset is blocked due to SOL/IDER session.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5731
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5732
	netdev->features = NETIF_F_SG |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5733
			   NETIF_F_HW_CSUM |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5734
			   NETIF_F_HW_VLAN_TX |
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5735
			   NETIF_F_HW_VLAN_RX;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5736
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5737
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5738
		netdev->features |= NETIF_F_HW_VLAN_FILTER;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5739
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5740
	netdev->features |= NETIF_F_TSO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5741
	netdev->features |= NETIF_F_TSO6;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5742
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5743
	netdev->vlan_features |= NETIF_F_TSO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5744
	netdev->vlan_features |= NETIF_F_TSO6;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5745
	netdev->vlan_features |= NETIF_F_HW_CSUM;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5746
	netdev->vlan_features |= NETIF_F_SG;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5747
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5748
	if (pci_using_dac)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5749
		netdev->features |= NETIF_F_HIGHDMA;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5750
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5751
	if (e1000e_enable_mng_pass_thru(&adapter->hw))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5752
		adapter->flags |= FLAG_MNG_PT_ENABLED;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5753
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5754
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5755
	 * before reading the NVM, reset the controller to
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5756
	 * put the device in a known good starting state
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5757
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5758
	adapter->hw.mac.ops.reset_hw(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5759
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5760
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5761
	 * systems with ASPM and others may see the checksum fail on the first
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5762
	 * attempt. Let's give it a few tries
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5763
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5764
	for (i = 0;; i++) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5765
		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5766
			break;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5767
		if (i == 2) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5768
			e_err("The NVM Checksum Is Not Valid\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5769
			err = -EIO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5770
			goto err_eeprom;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5771
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5772
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5773
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5774
	e1000_eeprom_checks(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5775
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5776
	/* copy the MAC address */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5777
	if (e1000e_read_mac_addr(&adapter->hw))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5778
		e_err("NVM Read Error while reading MAC address\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5779
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5780
	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5781
	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5782
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5783
	if (!is_valid_ether_addr(netdev->perm_addr)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5784
		e_err("Invalid MAC Address: %pM\n", netdev->perm_addr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5785
		err = -EIO;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5786
		goto err_eeprom;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5787
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5788
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5789
	init_timer(&adapter->watchdog_timer);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5790
	adapter->watchdog_timer.function = &e1000_watchdog;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5791
	adapter->watchdog_timer.data = (unsigned long) adapter;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5792
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5793
	init_timer(&adapter->phy_info_timer);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5794
	adapter->phy_info_timer.function = &e1000_update_phy_info;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5795
	adapter->phy_info_timer.data = (unsigned long) adapter;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5796
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5797
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5798
	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5799
	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5800
	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5801
	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5802
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5803
	/* Initialize link parameters. User can change them with ethtool */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5804
	adapter->hw.mac.autoneg = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5805
	adapter->fc_autoneg = 1;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5806
	adapter->hw.fc.requested_mode = e1000_fc_default;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5807
	adapter->hw.fc.current_mode = e1000_fc_default;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5808
	adapter->hw.phy.autoneg_advertised = 0x2f;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5809
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5810
	/* ring size defaults */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5811
	adapter->rx_ring->count = 256;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5812
	adapter->tx_ring->count = 256;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5813
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5814
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5815
	 * Initial Wake on LAN setting - If APM wake is enabled in
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5816
	 * the EEPROM, enable the ACPI Magic Packet filter
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5817
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5818
	if (adapter->flags & FLAG_APME_IN_WUC) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5819
		/* APME bit in EEPROM is mapped to WUC.APME */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5820
		eeprom_data = er32(WUC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5821
		eeprom_apme_mask = E1000_WUC_APME;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5822
		if (eeprom_data & E1000_WUC_PHY_WAKE)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5823
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5824
	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5825
		if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5826
		    (adapter->hw.bus.func == 1))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5827
			e1000_read_nvm(&adapter->hw,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5828
				NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5829
		else
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5830
			e1000_read_nvm(&adapter->hw,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5831
				NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5832
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5833
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5834
	/* fetch WoL from EEPROM */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5835
	if (eeprom_data & eeprom_apme_mask)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5836
		adapter->eeprom_wol |= E1000_WUFC_MAG;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5837
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5838
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5839
	 * now that we have the eeprom settings, apply the special cases
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5840
	 * where the eeprom may be wrong or the board simply won't support
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5841
	 * wake on lan on a particular port
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5842
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5843
	if (!(adapter->flags & FLAG_HAS_WOL))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5844
		adapter->eeprom_wol = 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5845
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5846
	/* initialize the wol settings based on the eeprom settings */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5847
	adapter->wol = adapter->eeprom_wol;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5848
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5849
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5850
	/* save off EEPROM version number */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5851
	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5852
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5853
	/* reset the hardware with the new settings */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5854
	e1000e_reset(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5855
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5856
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5857
	 * If the controller has AMT, do not set DRV_LOAD until the interface
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5858
	 * is up.  For all other cases, let the f/w know that the h/w is now
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5859
	 * under the control of the driver.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5860
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5861
	if (!(adapter->flags & FLAG_HAS_AMT))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5862
		e1000_get_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5863
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5864
	adapter->ecdev = ecdev_offer(netdev,ec_poll,THIS_MODULE);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5865
	if (adapter->ecdev) {
2582
87e502828b3f Use return value of ecdev_open(); thanks to Patrick Bruenn.
Florian Pose <fp@igh-essen.com>
parents: 2500
diff changeset
  5866
		err = ecdev_open(adapter->ecdev);
87e502828b3f Use return value of ecdev_open(); thanks to Patrick Bruenn.
Florian Pose <fp@igh-essen.com>
parents: 2500
diff changeset
  5867
		if (err) {
2290
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5868
			ecdev_withdraw(adapter->ecdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5869
			goto err_register;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5870
		}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5871
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5872
		strcpy(netdev->name, "eth%d");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5873
		err = register_netdev(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5874
		if (err)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5875
			goto err_register;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5876
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5877
		/* carrier off reporting is important to ethtool even BEFORE open */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5878
		netif_carrier_off(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5879
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5880
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5881
	e1000_print_device_info(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5882
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5883
	if (pci_dev_run_wake(pdev)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5884
		pm_runtime_set_active(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5885
		pm_runtime_enable(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5886
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5887
	pm_schedule_suspend(&pdev->dev, MSEC_PER_SEC);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5888
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5889
	return 0;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5890
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5891
err_register:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5892
	if (!(adapter->flags & FLAG_HAS_AMT))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5893
		e1000_release_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5894
err_eeprom:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5895
	if (!e1000_check_reset_block(&adapter->hw))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5896
		e1000_phy_hw_reset(&adapter->hw);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5897
err_hw_init:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5898
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5899
	kfree(adapter->tx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5900
	kfree(adapter->rx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5901
err_sw_init:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5902
	if (adapter->hw.flash_address)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5903
		iounmap(adapter->hw.flash_address);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5904
	e1000e_reset_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5905
err_flashmap:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5906
	iounmap(adapter->hw.hw_addr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5907
err_ioremap:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5908
	free_netdev(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5909
err_alloc_etherdev:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5910
	pci_release_selected_regions(pdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5911
	                             pci_select_bars(pdev, IORESOURCE_MEM));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5912
err_pci_reg:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5913
err_dma:
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5914
	pci_disable_device(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5915
	return err;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5916
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5917
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5918
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5919
 * e1000_remove - Device Removal Routine
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5920
 * @pdev: PCI device information struct
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5921
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5922
 * e1000_remove is called by the PCI subsystem to alert the driver
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5923
 * that it should release a PCI device.  The could be caused by a
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5924
 * Hot-Plug event, or because the driver is going to be removed from
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5925
 * memory.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5926
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5927
static void __devexit e1000_remove(struct pci_dev *pdev)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5928
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5929
	struct net_device *netdev = pci_get_drvdata(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5930
	struct e1000_adapter *adapter = netdev_priv(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5931
	bool down = test_bit(__E1000_DOWN, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5932
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5933
	pm_runtime_get_sync(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5934
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5935
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5936
	 * flush_scheduled work may reschedule our watchdog task, so
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5937
	 * explicitly disable watchdog tasks from being rescheduled
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5938
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5939
	if (!down)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5940
		set_bit(__E1000_DOWN, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5941
	del_timer_sync(&adapter->watchdog_timer);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5942
	del_timer_sync(&adapter->phy_info_timer);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5943
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5944
	cancel_work_sync(&adapter->reset_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5945
	cancel_work_sync(&adapter->watchdog_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5946
	cancel_work_sync(&adapter->downshift_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5947
	cancel_work_sync(&adapter->update_phy_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5948
	cancel_work_sync(&adapter->print_hang_task);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5949
	flush_scheduled_work();
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5950
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5951
	if (!(netdev->flags & IFF_UP))
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5952
		e1000_power_down_phy(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5953
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5954
	/* Don't lie to e1000_close() down the road. */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5955
	if (!down)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5956
		clear_bit(__E1000_DOWN, &adapter->state);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5957
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5958
	if (adapter->ecdev) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5959
		ecdev_close(adapter->ecdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5960
		ecdev_withdraw(adapter->ecdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5961
	} else {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5962
		unregister_netdev(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5963
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5964
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5965
	if (pci_dev_run_wake(pdev)) {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5966
		pm_runtime_disable(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5967
		pm_runtime_set_suspended(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5968
	}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5969
	pm_runtime_put_noidle(&pdev->dev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5970
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5971
	/*
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5972
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5973
	 * would have already happened in close and is redundant.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5974
	 */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5975
	e1000_release_hw_control(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5976
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5977
	e1000e_reset_interrupt_capability(adapter);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5978
	kfree(adapter->tx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5979
	kfree(adapter->rx_ring);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5980
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5981
	iounmap(adapter->hw.hw_addr);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5982
	if (adapter->hw.flash_address)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5983
		iounmap(adapter->hw.flash_address);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5984
	pci_release_selected_regions(pdev,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5985
	                             pci_select_bars(pdev, IORESOURCE_MEM));
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5986
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5987
	free_netdev(netdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5988
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5989
	/* AER disable */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5990
	pci_disable_pcie_error_reporting(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5991
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5992
	pci_disable_device(pdev);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5993
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5994
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5995
/* PCI Error Recovery (ERS) */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5996
static struct pci_error_handlers e1000_err_handler = {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5997
	.error_detected = e1000_io_error_detected,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5998
	.slot_reset = e1000_io_slot_reset,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5999
	.resume = e1000_io_resume,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6000
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6001
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6002
static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6003
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6004
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6005
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6006
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6007
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6008
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6009
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6010
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6011
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6012
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6013
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6014
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6015
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6016
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6017
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6018
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6019
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6020
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6021
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6022
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6023
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6024
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6025
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6026
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6027
	  board_80003es2lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6028
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6029
	  board_80003es2lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6030
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6031
	  board_80003es2lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6032
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6033
	  board_80003es2lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6034
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6035
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6036
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6037
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6038
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6039
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6040
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6041
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6042
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6043
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6044
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6045
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6046
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6047
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6048
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6049
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6050
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6051
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6052
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6053
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6054
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6055
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6056
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6057
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6058
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6059
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6060
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_V), board_ich10lan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6061
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6062
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6063
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6064
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6065
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6066
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6067
	{ }	/* terminate list */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6068
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6069
//MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6070
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6071
#ifdef CONFIG_PM_OPS
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6072
static const struct dev_pm_ops e1000_pm_ops = {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6073
	SET_SYSTEM_SLEEP_PM_OPS(e1000_suspend, e1000_resume)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6074
	SET_RUNTIME_PM_OPS(e1000_runtime_suspend,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6075
				e1000_runtime_resume, e1000_idle)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6076
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6077
#endif
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6078
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6079
/* PCI Device API Driver */
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6080
static struct pci_driver e1000_driver = {
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6081
	.name     = e1000e_driver_name,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6082
	.id_table = e1000_pci_tbl,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6083
	.probe    = e1000_probe,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6084
	.remove   = __devexit_p(e1000_remove),
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6085
#ifdef CONFIG_PM_OPS
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6086
	.driver.pm = &e1000_pm_ops,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6087
#endif
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6088
	.shutdown = e1000_shutdown,
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6089
	.err_handler = &e1000_err_handler
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6090
};
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6091
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6092
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6093
 * e1000_init_module - Driver Registration Routine
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6094
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6095
 * e1000_init_module is the first routine called when the driver is
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6096
 * loaded. All it does is register with the PCI subsystem.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6097
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6098
static int __init e1000_init_module(void)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6099
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6100
	int ret;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6101
	pr_info("EtherCAT-capable Intel(R) PRO/1000 Network Driver - %s\n",
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6102
		e1000e_driver_version);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6103
	pr_info("Copyright (c) 1999 - 2009 Intel Corporation.\n");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6104
	ret = pci_register_driver(&e1000_driver);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6105
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6106
	return ret;
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6107
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6108
module_init(e1000_init_module);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6109
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6110
/**
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6111
 * e1000_exit_module - Driver Exit Cleanup Routine
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6112
 *
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6113
 * e1000_exit_module is called just before the driver is removed
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6114
 * from memory.
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6115
 **/
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6116
static void __exit e1000_exit_module(void)
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6117
{
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6118
	pci_unregister_driver(&e1000_driver);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6119
}
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6120
module_exit(e1000_exit_module);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6121
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6122
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6123
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6124
MODULE_DESCRIPTION("Ethercat-capable Intel(R) PRO/1000 Network Driver");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6125
MODULE_LICENSE("GPL");
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6126
MODULE_VERSION(DRV_VERSION);
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6127
0a6fc3f5f418 Added e1000e driver for 2.6.35.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  6128
/* e1000_main.c */