devices/e1000e/netdev-2.6.33-ethercat.c
author Gavin Lambert <gavinl@compacsort.com>
Tue, 14 Apr 2015 09:33:24 -0400
changeset 2618 3affe9cd0b66
parent 2589 2b9c78543663
permissions -rw-r--r--
Ignore NXIO error otherwise this causes spam if network is empty or refclk not
selected yet, and syncing refclk time to master.
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2009 Intel Corporation.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
  vim: noexpandtab
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
*******************************************************************************/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/module.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/types.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/init.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/pci.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/vmalloc.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/pagemap.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/delay.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/netdevice.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <linux/tcp.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <linux/ipv6.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <net/checksum.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <net/ip6_checksum.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <linux/mii.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <linux/ethtool.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <linux/if_vlan.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
#include <linux/cpu.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include <linux/smp.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
#include <linux/pm_qos_params.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#include <linux/aer.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#include "e1000-2.6.33-ethercat.h"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
#define DRV_VERSION "1.0.2-k2"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
char e1000e_driver_name[] = "ec_e1000e";
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
const char e1000e_driver_version[] = DRV_VERSION;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
static const struct e1000_info *e1000_info_tbl[] = {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	[board_82571]		= &e1000_82571_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	[board_82572]		= &e1000_82572_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	[board_82573]		= &e1000_82573_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	[board_82574]		= &e1000_82574_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	[board_82583]		= &e1000_82583_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	[board_80003es2lan]	= &e1000_es2_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	[board_ich8lan]		= &e1000_ich8_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	[board_ich9lan]		= &e1000_ich9_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	[board_ich10lan]	= &e1000_ich10_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	[board_pchlan]		= &e1000_pch_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
 * e1000_desc_unused - calculate if we have unused descriptors
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
static int e1000_desc_unused(struct e1000_ring *ring)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	if (ring->next_to_clean > ring->next_to_use)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
		return ring->next_to_clean - ring->next_to_use - 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	return ring->count + ring->next_to_clean - ring->next_to_use - 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
 * e1000_receive_skb - helper function to handle Rx indications
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
 * @status: descriptor status field as written by hardware
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
 * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
 * @skb: pointer to sk_buff to be indicated to stack
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
static void e1000_receive_skb(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
			      struct net_device *netdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
			      struct sk_buff *skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
			      u8 status, __le16 vlan)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	skb->protocol = eth_type_trans(skb, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
				 le16_to_cpu(vlan), skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
		napi_gro_receive(&adapter->napi, skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
 * e1000_rx_checksum - Receive Checksum Offload for 82543
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
 * @adapter:     board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
 * @status_err:  receive descriptor status and error fields
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
 * @csum:	receive descriptor csum field
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
 * @sk_buff:     socket buffer with received data
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
			      u32 csum, struct sk_buff *skb)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	u16 status = (u16)status_err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	u8 errors = (u8)(status_err >> 24);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	skb->ip_summed = CHECKSUM_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
	/* Ignore Checksum bit is set */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	if (status & E1000_RXD_STAT_IXSM)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	/* TCP/UDP checksum error bit is set */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	if (errors & E1000_RXD_ERR_TCPE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
		/* let the stack verify checksum errors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
		adapter->hw_csum_err++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
	/* TCP/UDP Checksum has not been calculated */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
	if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	/* It must be a TCP or UDP packet with a valid checksum */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	if (status & E1000_RXD_STAT_TCPCS) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
		/* TCP checksum is good */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		skb->ip_summed = CHECKSUM_UNNECESSARY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
		 * IP fragment with UDP payload
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
		 * Hardware complements the payload checksum, so we undo it
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		 * and then put the value in host order for further stack use.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
		__sum16 sum = (__force __sum16)htons(csum);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
		skb->csum = csum_unfold(~sum);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
		skb->ip_summed = CHECKSUM_COMPLETE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
	adapter->hw_csum_good++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
				   int cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	struct e1000_rx_desc *rx_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	unsigned int bufsz = adapter->rx_buffer_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	i = rx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
	while (cleaned_count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
		if (skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
			skb_trim(skb, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
			goto map_skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
		if (!skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
			/* Better luck next round */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
			adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
		buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
map_skb:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
		buffer_info->dma = pci_map_single(pdev, skb->data,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
						  adapter->rx_buffer_len,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
						  PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
		if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
			dev_err(&pdev->dev, "RX DMA map failed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
			adapter->rx_dma_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
		rx_desc = E1000_RX_DESC(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	if (rx_ring->next_to_use != i) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		rx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		if (i-- == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
			i = (rx_ring->count - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
		 * Force memory writes to complete before letting h/w
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
		 * know there are new descriptors to fetch.  (Only
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
		 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
		 * such as IA-64).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
		wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
		writel(i, adapter->hw.hw_addr + rx_ring->tail);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
 * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
				      int cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	union e1000_rx_desc_packet_split *rx_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	struct e1000_ps_page *ps_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	unsigned int i, j;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	i = rx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
	while (cleaned_count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
			ps_page = &buffer_info->ps_pages[j];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
			if (j >= adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
				/* all unused desc entries get hw null ptr */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
				rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
				continue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
			if (!ps_page->page) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
				ps_page->page = alloc_page(GFP_ATOMIC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
				if (!ps_page->page) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
					adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
					goto no_buffers;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
				ps_page->dma = pci_map_page(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
						   ps_page->page,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
						   0, PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
						   PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
				if (pci_dma_mapping_error(pdev, ps_page->dma)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
					dev_err(&adapter->pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
					  "RX DMA page map failed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
					adapter->rx_dma_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
					goto no_buffers;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
			 * Refresh the desc even if buffer_addrs
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
			 * didn't change because each write-back
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
			 * erases this info.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
			rx_desc->read.buffer_addr[j+1] =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
			     cpu_to_le64(ps_page->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
		skb = netdev_alloc_skb_ip_align(netdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
						adapter->rx_ps_bsize0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
		if (!skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
			adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
		buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
		buffer_info->dma = pci_map_single(pdev, skb->data,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
						  adapter->rx_ps_bsize0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
						  PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
		if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
			dev_err(&pdev->dev, "RX DMA map failed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
			adapter->rx_dma_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
			/* cleanup skb */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
			dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
			buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
no_buffers:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	if (rx_ring->next_to_use != i) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
		rx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
		if (!(i--))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
			i = (rx_ring->count - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		 * Force memory writes to complete before letting h/w
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
		 * know there are new descriptors to fetch.  (Only
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
		 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
		 * such as IA-64).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
		wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		 * Hardware increments by 16 bytes, but packet split
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		 * descriptors are 32 bytes...so we increment tail
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
		 * twice as much.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		writel(i<<1, adapter->hw.hw_addr + rx_ring->tail);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
 * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
 * @cleaned_count: number of buffers to allocate this pass
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
                                         int cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	struct e1000_rx_desc *rx_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	unsigned int bufsz = 256 - 16 /* for skb_reserve */;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
	i = rx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	while (cleaned_count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		if (skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
			skb_trim(skb, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
			goto check_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
		skb = netdev_alloc_skb_ip_align(netdev, bufsz);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
		if (unlikely(!skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
			/* Better luck next round */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
			adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
		buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
check_page:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
		/* allocate a new page if necessary */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		if (!buffer_info->page) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
			buffer_info->page = alloc_page(GFP_ATOMIC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
			if (unlikely(!buffer_info->page)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
				adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
		if (!buffer_info->dma)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
			buffer_info->dma = pci_map_page(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
			                                buffer_info->page, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
			                                PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
			                                PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
		rx_desc = E1000_RX_DESC(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		if (unlikely(++i == rx_ring->count))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	if (likely(rx_ring->next_to_use != i)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
		rx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
		if (unlikely(i-- == 0))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
			i = (rx_ring->count - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
		/* Force memory writes to complete before letting h/w
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
		 * know there are new descriptors to fetch.  (Only
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		 * such as IA-64). */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
		wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		writel(i, adapter->hw.hw_addr + rx_ring->tail);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
 * the return value indicates whether actual cleaning was done, there
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
			       int *work_done, int work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	struct e1000_rx_desc *rx_desc, *next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	struct e1000_buffer *buffer_info, *next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	u32 length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	int cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	bool cleaned = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	i = rx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	rx_desc = E1000_RX_DESC(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	while (rx_desc->status & E1000_RXD_STAT_DD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
		struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
		u8 status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		if (*work_done >= work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
		(*work_done)++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		status = rx_desc->status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
		if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
			buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		prefetch(skb->data - NET_IP_ALIGN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
		next_rxd = E1000_RX_DESC(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
		prefetch(next_rxd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
		next_buffer = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
		cleaned = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
		cleaned_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		pci_unmap_single(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
				 buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
				 adapter->rx_buffer_len,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
				 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
		length = le16_to_cpu(rx_desc->length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
		 * !EOP means multiple descriptors were used to store a single
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		 * packet, if that's the case we need to toss it.  In fact, we
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		 * need to toss every packet with the EOP bit clear and the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
		 * next frame that _does_ have the EOP bit set, as it is by
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
		 * definition only a frame fragment
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
			adapter->flags2 |= FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
			/* All receives must fit into a single buffer */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
			e_dbg("Receive packet consumed multiple buffers\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
			/* recycle */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
			buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
			if (status & E1000_RXD_STAT_EOP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		if (!adapter->ecdev && (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
			/* recycle */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
			buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
		/* adjust length to remove Ethernet CRC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
			length -= 4;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
		total_rx_bytes += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
		total_rx_packets++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
		 * code added for copybreak, this should improve
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
		 * performance for small packets with large amounts
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
		 * of reassembly being done in the stack
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
		if (!adapter->ecdev && length < copybreak) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
			struct sk_buff *new_skb =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
			    netdev_alloc_skb_ip_align(netdev, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
			if (new_skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
				skb_copy_to_linear_data_offset(new_skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
							       -NET_IP_ALIGN,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
							       (skb->data -
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
								NET_IP_ALIGN),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
							       (length +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
								NET_IP_ALIGN));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
				/* save the skb in buffer_info as good */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
				skb = new_skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
			/* else just continue with the old one */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		/* end copybreak code */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
		skb_put(skb, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		/* Receive Checksum Offload */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		e1000_rx_checksum(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
				  (u32)(status) |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
				  ((u32)(rx_desc->errors) << 24),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
				  le16_to_cpu(rx_desc->csum), skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
		if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
			ecdev_receive(adapter->ecdev, skb->data, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
			adapter->ec_watchdog_jiffies = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
			e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
next_desc:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
		rx_desc->status = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		/* return some buffers to hardware, one at a time is too slow */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
			adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
			cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
		/* use prefetched values */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
		rx_desc = next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
		buffer_info = next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	rx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
	cleaned_count = e1000_desc_unused(rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
	if (cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
		adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	adapter->total_rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	adapter->total_rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	netdev->stats.rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
	netdev->stats.rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	return cleaned;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
static void e1000_put_txbuf(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
			     struct e1000_buffer *buffer_info)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	if (buffer_info->dma) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
		if (buffer_info->mapped_as_page)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
			pci_unmap_page(adapter->pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
				       buffer_info->length, PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
			pci_unmap_single(adapter->pdev,	buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
					 buffer_info->length,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
					 PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
		buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	if (buffer_info->skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
		dev_kfree_skb_any(buffer_info->skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
	buffer_info->time_stamp = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
static void e1000_print_hw_hang(struct work_struct *work)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	                                             struct e1000_adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	                                             print_hang_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	unsigned int i = tx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	u16 phy_status, phy_1000t_status, phy_ext_status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	u16 pci_status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	e1e_rphy(hw, PHY_STATUS, &phy_status);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	e1e_rphy(hw, PHY_1000T_STATUS, &phy_1000t_status);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	e1e_rphy(hw, PHY_EXT_STATUS, &phy_ext_status);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_status);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	/* detected Hardware unit hang */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	e_err("Detected Hardware Unit Hang:\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	      "  TDH                  <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	      "  TDT                  <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	      "  next_to_use          <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	      "  next_to_clean        <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	      "buffer_info[next_to_clean]:\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	      "  time_stamp           <%lx>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
	      "  next_to_watch        <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
	      "  jiffies              <%lx>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	      "  next_to_watch.status <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	      "MAC Status             <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	      "PHY Status             <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	      "PHY 1000BASE-T Status  <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	      "PHY Extended Status    <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	      "PCI Status             <%x>\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	      readl(adapter->hw.hw_addr + tx_ring->head),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	      readl(adapter->hw.hw_addr + tx_ring->tail),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	      tx_ring->next_to_use,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	      tx_ring->next_to_clean,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	      tx_ring->buffer_info[eop].time_stamp,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
	      eop,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
	      jiffies,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	      eop_desc->upper.fields.status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
	      er32(STATUS),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
	      phy_status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	      phy_1000t_status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
	      phy_ext_status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
	      pci_status);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
 * the return value indicates whether actual cleaning was done, there
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
	struct e1000_tx_desc *tx_desc, *eop_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
	unsigned int i, eop;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
	unsigned int count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	i = tx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	eop = tx_ring->buffer_info[i].next_to_watch;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	       (count < tx_ring->count)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
		bool cleaned = false;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
		for (; !cleaned; count++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
			tx_desc = E1000_TX_DESC(*tx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
			buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
			cleaned = (i == eop);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
			if (cleaned) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
				struct sk_buff *skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
				unsigned int segs, bytecount;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
				segs = skb_shinfo(skb)->gso_segs ?: 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
				/* multiply data chunks by size of headers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
				bytecount = ((segs - 1) * skb_headlen(skb)) +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
					    skb->len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
				total_tx_packets += segs;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
				total_tx_bytes += bytecount;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
			if (!adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
				e1000_put_txbuf(adapter, buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
			tx_desc->upper.data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
			i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
			if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
				i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
		if (i == tx_ring->next_to_use)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		eop = tx_ring->buffer_info[i].next_to_watch;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	tx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
#define TX_WAKE_THRESHOLD 32
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	if (!adapter->ecdev && count && netif_carrier_ok(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
		/* Make sure that anybody stopping the queue after this
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
		 * sees the new next_to_clean.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
		smp_mb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
		if (netif_queue_stopped(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
			netif_wake_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
			++adapter->restart_queue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	if (!adapter->ecdev && adapter->detect_tx_hung) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
		 * Detect a transmit hang in hardware, this serializes the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		 * check with the clearing of time_stamp and movement of i
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		adapter->detect_tx_hung = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		if (tx_ring->buffer_info[i].time_stamp &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
		    time_after(jiffies, tx_ring->buffer_info[i].time_stamp
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
			       + (adapter->tx_timeout_factor * HZ)) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
			schedule_work(&adapter->print_hang_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
			netif_stop_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	adapter->total_tx_bytes += total_tx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	adapter->total_tx_packets += total_tx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	netdev->stats.tx_bytes += total_tx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	netdev->stats.tx_packets += total_tx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
	return (count < tx_ring->count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
 * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
 * the return value indicates whether actual cleaning was done, there
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
				  int *work_done, int work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	struct e1000_buffer *buffer_info, *next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	struct e1000_ps_page *ps_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	unsigned int i, j;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
	u32 length, staterr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
	int cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
	bool cleaned = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	i = rx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
	rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	while (staterr & E1000_RXD_STAT_DD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		if (*work_done >= work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
		(*work_done)++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
		/* in the packet split case this is header only */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
		prefetch(skb->data - NET_IP_ALIGN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
		next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		prefetch(next_rxd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		next_buffer = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		cleaned = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
		cleaned_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		pci_unmap_single(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
				 adapter->rx_ps_bsize0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
				 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		/* see !EOP comment in other rx routine */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		if (!(staterr & E1000_RXD_STAT_EOP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
			adapter->flags2 |= FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
			e_dbg("Packet Split buffers didn't pick up the full "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
			      "packet\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
			if (!adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
				dev_kfree_skb_irq(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
			if (staterr & E1000_RXD_STAT_EOP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
			if (!adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
				dev_kfree_skb_irq(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		length = le16_to_cpu(rx_desc->wb.middle.length0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
		if (!length) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
			e_dbg("Last part of the packet spanning multiple "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
			      "descriptors\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
			if (!adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
				dev_kfree_skb_irq(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
		/* Good Receive */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		skb_put(skb, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
		{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
		 * this looks ugly, but it seems compiler issues make it
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
		 * more efficient than reusing j
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		 * page alloc/put takes too long and effects small packet
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
		 * throughput, so unsplit small packets and save the alloc/put
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
		 * only valid in softirq (napi) context to call kmap_*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		if (l1 && (l1 <= copybreak) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		    ((length + l1) <= adapter->rx_ps_bsize0)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
			u8 *vaddr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
			ps_page = &buffer_info->ps_pages[0];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
			 * there is no documentation about how to call
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
			 * kmap_atomic, so we can't hold the mapping
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
			 * very long
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
			pci_dma_sync_single_for_cpu(pdev, ps_page->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
			vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
			memcpy(skb_tail_pointer(skb), vaddr, l1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			pci_dma_sync_single_for_device(pdev, ps_page->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
			/* remove the CRC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
			if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
				l1 -= 4;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
			skb_put(skb, l1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
			goto copydone;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		} /* if */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
			length = le16_to_cpu(rx_desc->wb.upper.length[j]);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
			if (!length)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
			ps_page = &buffer_info->ps_pages[j];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
			pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
				       PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
			ps_page->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
			skb_fill_page_desc(skb, j, ps_page->page, 0, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
			ps_page->page = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
			skb->len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
			skb->data_len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
			skb->truesize += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
		/* strip the ethernet crc, problem is we're using pages now so
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
		 * this whole operation can get a little cpu intensive
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
			pskb_trim(skb, skb->len - 4);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
copydone:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		total_rx_bytes += skb->len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
		total_rx_packets++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
		e1000_rx_checksum(adapter, staterr, le16_to_cpu(
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
			rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
		if (rx_desc->wb.upper.header_status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
			adapter->rx_hdr_split++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
		if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
			ecdev_receive(adapter->ecdev, skb->data, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
			adapter->ec_watchdog_jiffies = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
			e1000_receive_skb(adapter, netdev, skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
					  staterr, rx_desc->wb.middle.vlan);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
next_desc:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
		if (!adapter->ecdev) buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
		/* return some buffers to hardware, one at a time is too slow */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
			adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
			cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
		/* use prefetched values */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
		rx_desc = next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
		buffer_info = next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	rx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	cleaned_count = e1000_desc_unused(rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	if (cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
		adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
	adapter->total_rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	adapter->total_rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	netdev->stats.rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	netdev->stats.rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
	return cleaned;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
 * e1000_consume_page - helper function
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
                               u16 length)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	bi->page = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	skb->len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	skb->data_len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	skb->truesize += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
 * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
 * the return value indicates whether actual cleaning was done, there
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
                                     int *work_done, int work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	struct e1000_rx_desc *rx_desc, *next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	struct e1000_buffer *buffer_info, *next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	u32 length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	int cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	bool cleaned = false;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	unsigned int total_rx_bytes=0, total_rx_packets=0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
	i = rx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	rx_desc = E1000_RX_DESC(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
	while (rx_desc->status & E1000_RXD_STAT_DD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
		struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
		u8 status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		if (*work_done >= work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		(*work_done)++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
		status = rx_desc->status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
		if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
			buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
		++i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
		next_rxd = E1000_RX_DESC(*rx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
		prefetch(next_rxd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		next_buffer = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
		cleaned = true;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
		cleaned_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
		pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
		               PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
		buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
		length = le16_to_cpu(rx_desc->length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
		/* errors is only valid for DD + EOP descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
		if (!adapter->ecdev && unlikely((status & E1000_RXD_STAT_EOP) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
				/* recycle both page and skb */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
				/* an error means any chain goes out the window
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
				 * too */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
				if (rx_ring->rx_skb_top)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
					dev_kfree_skb(rx_ring->rx_skb_top);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
				rx_ring->rx_skb_top = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
				goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
#define rxtop rx_ring->rx_skb_top
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		if (!(status & E1000_RXD_STAT_EOP)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
			/* this descriptor is only the beginning (or middle) */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
			if (!rxtop) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
				/* this is the beginning of a chain */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
				rxtop = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
				skb_fill_page_desc(rxtop, 0, buffer_info->page,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
				                   0, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
			} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
				/* this is the middle of a chain */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
				skb_fill_page_desc(rxtop,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
				    skb_shinfo(rxtop)->nr_frags,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
				    buffer_info->page, 0, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
				/* re-use the skb, only consumed the page */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
			e1000_consume_page(buffer_info, rxtop, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
			if (rxtop) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
				/* end of the chain */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
				skb_fill_page_desc(rxtop,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
				    skb_shinfo(rxtop)->nr_frags,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
				    buffer_info->page, 0, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
				/* re-use the current skb, we only consumed the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
				 * page */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
				skb = rxtop;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
				rxtop = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
				e1000_consume_page(buffer_info, skb, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
			} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
				/* no chain, got EOP, this buf is the packet
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
				 * copybreak to save the put_page/alloc_page */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
				if (length <= copybreak &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
				    skb_tailroom(skb) >= length) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
					u8 *vaddr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
					vaddr = kmap_atomic(buffer_info->page,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
					                   KM_SKB_DATA_SOFTIRQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
					memcpy(skb_tail_pointer(skb), vaddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
					       length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
					kunmap_atomic(vaddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
					              KM_SKB_DATA_SOFTIRQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
					/* re-use the page, so don't erase
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
					 * buffer_info->page */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
					skb_put(skb, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
				} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
					skb_fill_page_desc(skb, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
					                   buffer_info->page, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
				                           length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
					e1000_consume_page(buffer_info, skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
					                   length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		/* Receive Checksum Offload XXX recompute due to CRC strip? */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		e1000_rx_checksum(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		                  (u32)(status) |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		                  ((u32)(rx_desc->errors) << 24),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		                  le16_to_cpu(rx_desc->csum), skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		/* probably a little skewed due to removing CRC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		total_rx_bytes += skb->len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		total_rx_packets++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		/* eth type trans needs skb->data to point to something */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		if (!adapter->ecdev && !pskb_may_pull(skb, ETH_HLEN)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
			e_err("pskb_may_pull failed.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
			dev_kfree_skb(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
			ecdev_receive(adapter->ecdev, skb->data, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
			adapter->ec_watchdog_jiffies = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
			e1000_receive_skb(adapter, netdev, skb, status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
			                  rx_desc->special);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
next_desc:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
		rx_desc->status = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		/* return some buffers to hardware, one at a time is too slow */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
			adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
			cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		/* use prefetched values */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		rx_desc = next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		buffer_info = next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
	rx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	cleaned_count = e1000_desc_unused(rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	if (cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	adapter->total_rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	adapter->total_rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
	netdev->stats.rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
	netdev->stats.rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	return cleaned;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	struct e1000_ps_page *ps_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	unsigned int i, j;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	/* Free all the Rx ring sk_buffs */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
	for (i = 0; i < rx_ring->count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		if (buffer_info->dma) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			if (adapter->clean_rx == e1000_clean_rx_irq)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
				pci_unmap_single(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
						 adapter->rx_buffer_len,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
						 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
				pci_unmap_page(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
				               PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
				               PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
				pci_unmap_single(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
						 adapter->rx_ps_bsize0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
						 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
			buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		if (buffer_info->page) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
			put_page(buffer_info->page);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
			buffer_info->page = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
		if (buffer_info->skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			dev_kfree_skb(buffer_info->skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		for (j = 0; j < PS_PAGE_BUFFERS; j++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
			ps_page = &buffer_info->ps_pages[j];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
			if (!ps_page->page)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
			pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
				       PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
			ps_page->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
			put_page(ps_page->page);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
			ps_page->page = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	/* there also may be some cached data from a chained receive */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	if (rx_ring->rx_skb_top) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
		dev_kfree_skb(rx_ring->rx_skb_top);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
		rx_ring->rx_skb_top = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	/* Zero out the descriptor ring */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	memset(rx_ring->desc, 0, rx_ring->size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	rx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	rx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	writel(0, adapter->hw.hw_addr + rx_ring->head);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
	writel(0, adapter->hw.hw_addr + rx_ring->tail);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
static void e1000e_downshift_workaround(struct work_struct *work)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
					struct e1000_adapter, downshift_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
 * e1000_intr_msi - Interrupt Handler
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
 * @irq: interrupt number
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
 * @data: pointer to a network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
static irqreturn_t e1000_intr_msi(int irq, void *data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	u32 icr = er32(ICR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		int ec_work_done = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		adapter->clean_rx(adapter, &ec_work_done, 100);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		e1000_clean_tx_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	 * read ICR disables interrupts using IAM
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	if (icr & E1000_ICR_LSC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		hw->mac.get_link_status = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		 * ICH8 workaround-- Call gig speed drop workaround on cable
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		 * disconnect (LSC) before accessing any PHY registers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		    (!(er32(STATUS) & E1000_STATUS_LU)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
			schedule_work(&adapter->downshift_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		 * 80003ES2LAN workaround-- For packet buffer work-around on
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		 * link down event; disable receives here in the ISR and reset
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		 * adapter in watchdog
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		if (netif_carrier_ok(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
			/* disable receives */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
			u32 rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
			adapter->flags |= FLAG_RX_RESTART_NOW;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		/* guard against interrupt when we're going down */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	if (napi_schedule_prep(&adapter->napi)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		adapter->total_tx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		adapter->total_tx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		adapter->total_rx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		adapter->total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		__napi_schedule(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
 * e1000_intr - Interrupt Handler
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
 * @irq: interrupt number
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
 * @data: pointer to a network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
static irqreturn_t e1000_intr(int irq, void *data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	u32 rctl, icr = er32(ICR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
	if (!icr || test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
		return IRQ_NONE;  /* Not our interrupt */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	 * IMS will not auto-mask if INT_ASSERTED is not set, and if it is
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	 * not set, then the adapter didn't send an interrupt
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	if (!adapter->ecdev && !(icr & E1000_ICR_INT_ASSERTED))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		return IRQ_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	 * Interrupt Auto-Mask...upon reading ICR,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	 * interrupts are masked.  No need for the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	 * IMC write
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	if (!adapter->ecdev && (icr & E1000_ICR_LSC)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
		hw->mac.get_link_status = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
		 * ICH8 workaround-- Call gig speed drop workaround on cable
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		 * disconnect (LSC) before accessing any PHY registers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		    (!(er32(STATUS) & E1000_STATUS_LU)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
			schedule_work(&adapter->downshift_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
		 * 80003ES2LAN workaround--
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
		 * For packet buffer work-around on link down event;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		 * disable receives here in the ISR and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		 * reset adapter in watchdog
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
		if (netif_carrier_ok(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
			/* disable receives */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
			rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
			adapter->flags |= FLAG_RX_RESTART_NOW;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		/* guard against interrupt when we're going down */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		int ec_work_done = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		adapter->clean_rx(adapter, &ec_work_done, 100);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		e1000_clean_tx_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	if (napi_schedule_prep(&adapter->napi)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
		adapter->total_tx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
		adapter->total_tx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
		adapter->total_rx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
		adapter->total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
		__napi_schedule(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
static irqreturn_t e1000_msix_other(int irq, void *data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
	u32 icr = er32(ICR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
		if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
			ew32(IMS, E1000_IMS_OTHER);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		return IRQ_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	if (icr & adapter->eiac_mask)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
		ew32(ICS, (icr & adapter->eiac_mask));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	if (icr & E1000_ICR_OTHER) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		if (!(icr & E1000_ICR_LSC))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
			goto no_link_interrupt;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		hw->mac.get_link_status = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
		/* guard against interrupt when we're going down */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
		if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
no_link_interrupt:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
static irqreturn_t e1000_intr_msix_tx(int irq, void *data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
	adapter->total_tx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
	adapter->total_tx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
	if (!e1000_clean_tx_irq(adapter))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
		/* Ring was not completely cleaned, so fire another interrupt */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
		ew32(ICS, tx_ring->ims_val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
static irqreturn_t e1000_intr_msix_rx(int irq, void *data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	/* Write the ITR value calculated at the end of the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	 * previous interrupt.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	if (adapter->rx_ring->set_itr) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
		writel(1000000000 / (adapter->rx_ring->itr_val * 256),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
		       adapter->hw.hw_addr + adapter->rx_ring->itr_register);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
		adapter->rx_ring->set_itr = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
	if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		int ec_work_done = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
		adapter->clean_rx(adapter, &ec_work_done, 100);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		if (napi_schedule_prep(&adapter->napi)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
			adapter->total_rx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
			adapter->total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
			__napi_schedule(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
 * e1000_configure_msix - Configure MSI-X hardware
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
 * e1000_configure_msix sets up the hardware to properly
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
 * generate MSI-X interrupts.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
static void e1000_configure_msix(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	int vector = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	u32 ctrl_ext, ivar = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	adapter->eiac_mask = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
	/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	if (hw->mac.type == e1000_82574) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
		u32 rfctl = er32(RFCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
		rfctl |= E1000_RFCTL_ACK_DIS;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
		ew32(RFCTL, rfctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
#define E1000_IVAR_INT_ALLOC_VALID	0x8
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
	/* Configure Rx vector */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
	rx_ring->ims_val = E1000_IMS_RXQ0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	adapter->eiac_mask |= rx_ring->ims_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
	if (rx_ring->itr_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		writel(1000000000 / (rx_ring->itr_val * 256),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		       hw->hw_addr + rx_ring->itr_register);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		writel(1, hw->hw_addr + rx_ring->itr_register);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	/* Configure Tx vector */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
	tx_ring->ims_val = E1000_IMS_TXQ0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
	if (tx_ring->itr_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
		writel(1000000000 / (tx_ring->itr_val * 256),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
		       hw->hw_addr + tx_ring->itr_register);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
		writel(1, hw->hw_addr + tx_ring->itr_register);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
	adapter->eiac_mask |= tx_ring->ims_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	/* set vector for Other Causes, e.g. link changes */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	if (rx_ring->itr_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
		writel(1000000000 / (rx_ring->itr_val * 256),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		       hw->hw_addr + E1000_EITR_82574(vector));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
		writel(1, hw->hw_addr + E1000_EITR_82574(vector));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	/* Cause Tx interrupts on every write back */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	ivar |= (1 << 31);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	ew32(IVAR, ivar);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	/* enable MSI-X PBA support */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	/* Auto-Mask Other interrupts upon ICR read */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
#define E1000_EIAC_MASK_82574   0x01F00000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
	ew32(CTRL_EXT, ctrl_ext);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
		pci_disable_msix(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
		kfree(adapter->msix_entries);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		adapter->msix_entries = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
		pci_disable_msi(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
		adapter->flags &= ~FLAG_MSI_ENABLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
	return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
 * e1000e_set_interrupt_capability - set MSI or MSI-X if supported
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
 * Attempt to configure interrupts using the best available
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
 * capabilities of the hardware and kernel.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	int numvecs, i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	switch (adapter->int_mode) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	case E1000E_INT_MODE_MSIX:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
		if (adapter->flags & FLAG_HAS_MSIX) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
			numvecs = 3; /* RxQ0, TxQ0 and other */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
			adapter->msix_entries = kcalloc(numvecs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
						      sizeof(struct msix_entry),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
						      GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
			if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
				for (i = 0; i < numvecs; i++)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
					adapter->msix_entries[i].entry = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
				err = pci_enable_msix(adapter->pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
						      adapter->msix_entries,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
						      numvecs);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
				if (err == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
					return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
			/* MSI-X failed, so fall through and try MSI */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
			e_err("Failed to initialize MSI-X interrupts.  "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
			      "Falling back to MSI interrupts.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
			e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		adapter->int_mode = E1000E_INT_MODE_MSI;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		/* Fall through */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	case E1000E_INT_MODE_MSI:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
		if (!pci_enable_msi(adapter->pdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
			adapter->flags |= FLAG_MSI_ENABLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
			e_err("Failed to initialize MSI interrupts.  Falling "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
			      "back to legacy interrupts.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		/* Fall through */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	case E1000E_INT_MODE_LEGACY:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		/* Don't do anything; this is the system default */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
	return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
 * e1000_request_msix - Initialize MSI-X interrupts
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
 * e1000_request_msix allocates MSI-X vectors and requests interrupts from the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
 * kernel.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
static int e1000_request_msix(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	int err = 0, vector = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
		sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	err = request_irq(adapter->msix_entries[vector].vector,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
			  e1000_intr_msix_rx, 0, adapter->rx_ring->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
			  netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
	adapter->rx_ring->itr_register = E1000_EITR_82574(vector);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	adapter->rx_ring->itr_val = adapter->itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	err = request_irq(adapter->msix_entries[vector].vector,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
			  e1000_intr_msix_tx, 0, adapter->tx_ring->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
			  netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
	adapter->tx_ring->itr_register = E1000_EITR_82574(vector);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	adapter->tx_ring->itr_val = adapter->itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	err = request_irq(adapter->msix_entries[vector].vector,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
			  e1000_msix_other, 0, netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	e1000_configure_msix(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
out:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
 * e1000_request_irq - initialize interrupts
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
 * Attempts to configure interrupts using the best available
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
 * capabilities of the hardware and kernel.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
static int e1000_request_irq(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
		err = e1000_request_msix(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
		if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
			return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
		/* fall back to MSI */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		adapter->int_mode = E1000E_INT_MODE_MSI;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	if (adapter->flags & FLAG_MSI_ENABLED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		err = request_irq(adapter->pdev->irq, e1000_intr_msi, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
				  netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
			return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		/* fall back to legacy interrupt */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	err = request_irq(adapter->pdev->irq, e1000_intr, IRQF_SHARED,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
			  netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
		e_err("Unable to allocate interrupt, Error: %d\n", err);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
static void e1000_free_irq(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
		int vector = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
		free_irq(adapter->msix_entries[vector].vector, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
		vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		free_irq(adapter->msix_entries[vector].vector, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
		vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
		/* Other Causes interrupt vector */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
		free_irq(adapter->msix_entries[vector].vector, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	free_irq(adapter->pdev->irq, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
 * e1000_irq_disable - Mask off interrupt generation on the NIC
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
static void e1000_irq_disable(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	ew32(IMC, ~0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
	if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
		ew32(EIAC_82574, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	synchronize_irq(adapter->pdev->irq);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
 * e1000_irq_enable - Enable default interrupt generation settings
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
static void e1000_irq_enable(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		ew32(IMS, IMS_ENABLE_MASK);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
 * e1000_get_hw_control - get control of the h/w from f/w
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
 * e1000_get_hw_control sets {CTRL_EXT|SWSM}:DRV_LOAD bit.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
 * For ASF and Pass Through versions of f/w this means that
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
 * the driver is loaded. For AMT version (only with 82573)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
 * of the f/w this means that the network i/f is open.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
static void e1000_get_hw_control(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	u32 ctrl_ext;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	u32 swsm;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	/* Let firmware know the driver has taken over */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		swsm = er32(SWSM);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
 * e1000_release_hw_control - release control of the h/w to f/w
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
 * e1000_release_hw_control resets {CTRL_EXT|SWSM}:DRV_LOAD bit.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
 * For ASF and Pass Through versions of f/w this means that the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
 * driver is no longer loaded. For AMT version (only with 82573) i
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
 * of the f/w this means that the network i/f is closed.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
static void e1000_release_hw_control(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	u32 ctrl_ext;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	u32 swsm;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	/* Let firmware taken over control of h/w */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
	if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		swsm = er32(SWSM);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
 * @e1000_alloc_ring - allocate memory for a ring structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
				struct e1000_ring *ring)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
					GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	if (!ring->desc)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
		return -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
 * e1000e_setup_tx_resources - allocate Tx resources (Descriptors)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
 * Return 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	int err = -ENOMEM, size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
	size = sizeof(struct e1000_buffer) * tx_ring->count;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	tx_ring->buffer_info = vmalloc(size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	if (!tx_ring->buffer_info)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	memset(tx_ring->buffer_info, 0, size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	/* round up to nearest 4K */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
	tx_ring->size = ALIGN(tx_ring->size, 4096);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
	err = e1000_alloc_ring_dma(adapter, tx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	tx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	tx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
err:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	vfree(tx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
 * e1000e_setup_rx_resources - allocate Rx resources (Descriptors)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
 * Returns 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
	int i, size, desc_len, err = -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
	size = sizeof(struct e1000_buffer) * rx_ring->count;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
	rx_ring->buffer_info = vmalloc(size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	if (!rx_ring->buffer_info)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	memset(rx_ring->buffer_info, 0, size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
	for (i = 0; i < rx_ring->count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
						sizeof(struct e1000_ps_page),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
						GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		if (!buffer_info->ps_pages)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
			goto err_pages;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
	desc_len = sizeof(union e1000_rx_desc_packet_split);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
	/* Round up to nearest 4K */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
	rx_ring->size = rx_ring->count * desc_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	rx_ring->size = ALIGN(rx_ring->size, 4096);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
	err = e1000_alloc_ring_dma(adapter, rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		goto err_pages;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	rx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
	rx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	rx_ring->rx_skb_top = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
err_pages:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
	for (i = 0; i < rx_ring->count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
		kfree(buffer_info->ps_pages);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
err:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
	vfree(rx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
	e_err("Unable to allocate memory for the transmit descriptor ring\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
 * e1000_clean_tx_ring - Free Tx Buffers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	unsigned long size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
	for (i = 0; i < tx_ring->count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		e1000_put_txbuf(adapter, buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
	size = sizeof(struct e1000_buffer) * tx_ring->count;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	memset(tx_ring->buffer_info, 0, size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	memset(tx_ring->desc, 0, tx_ring->size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
	tx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
	tx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
	writel(0, adapter->hw.hw_addr + tx_ring->head);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	writel(0, adapter->hw.hw_addr + tx_ring->tail);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
 * e1000e_free_tx_resources - Free Tx Resources per Queue
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
 * Free all transmit software resources
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
void e1000e_free_tx_resources(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
	e1000_clean_tx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
	vfree(tx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	tx_ring->buffer_info = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
			  tx_ring->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
	tx_ring->desc = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
 * e1000e_free_rx_resources - Free Rx Resources
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
 * Free all receive software resources
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
void e1000e_free_rx_resources(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
	int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
	e1000_clean_rx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
	for (i = 0; i < rx_ring->count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
		kfree(rx_ring->buffer_info[i].ps_pages);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	vfree(rx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
	rx_ring->buffer_info = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
			  rx_ring->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
	rx_ring->desc = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
 * e1000_update_itr - update the dynamic ITR value based on statistics
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
 * @adapter: pointer to adapter
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
 * @itr_setting: current adapter->itr
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
 * @packets: the number of packets during this measurement interval
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
 * @bytes: the number of bytes during this measurement interval
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
 *      Stores a new ITR value based on packets and byte
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
 *      counts during the last interrupt.  The advantage of per interrupt
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
 *      computation is faster updates and more accurate ITR for the current
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
 *      traffic pattern.  Constants in this function were computed
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
 *      based on theoretical maximum wire speed and thresholds were set based
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
 *      on testing data as well as attempting to minimize response time
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
 *      while increasing bulk throughput.  This functionality is controlled
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
 *      by the InterruptThrottleRate module parameter.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
				     u16 itr_setting, int packets,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
				     int bytes)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
	unsigned int retval = itr_setting;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
	if (packets == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		goto update_itr_done;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
	switch (itr_setting) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	case lowest_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		/* handle TSO and jumbo frames */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
		if (bytes/packets > 8000)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
			retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		else if ((packets < 5) && (bytes > 512)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
			retval = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	case low_latency:  /* 50 usec aka 20000 ints/s */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		if (bytes > 10000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
			/* this if handles the TSO accounting */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
			if (bytes/packets > 8000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
				retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
			} else if ((packets < 10) || ((bytes/packets) > 1200)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
				retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
			} else if ((packets > 35)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
				retval = lowest_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		} else if (bytes/packets > 2000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
			retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
		} else if (packets <= 2 && bytes < 512) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			retval = lowest_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
	case bulk_latency: /* 250 usec aka 4000 ints/s */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
		if (bytes > 25000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
			if (packets > 35) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
				retval = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
		} else if (bytes < 6000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
			retval = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
update_itr_done:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
static void e1000_set_itr(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	u16 current_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
	u32 new_itr = adapter->itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
	if (adapter->link_speed != SPEED_1000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
		current_itr = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		new_itr = 4000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
		goto set_itr_now;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
	adapter->tx_itr = e1000_update_itr(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
				    adapter->tx_itr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
				    adapter->total_tx_packets,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
				    adapter->total_tx_bytes);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		adapter->tx_itr = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
	adapter->rx_itr = e1000_update_itr(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
				    adapter->rx_itr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
				    adapter->total_rx_packets,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
				    adapter->total_rx_bytes);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
		adapter->rx_itr = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
	switch (current_itr) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
	/* counts and packets in update_itr are dependent on these numbers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
	case lowest_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
		new_itr = 70000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
	case low_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
		new_itr = 20000; /* aka hwitr = ~200 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	case bulk_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
		new_itr = 4000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
set_itr_now:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
	if (new_itr != adapter->itr) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
		 * this attempts to bias the interrupt rate towards Bulk
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
		 * by adding intermediate steps when interrupt rate is
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
		 * increasing
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
		new_itr = new_itr > adapter->itr ?
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
			     min(adapter->itr + (new_itr >> 2), new_itr) :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
			     new_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
		adapter->itr = new_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
		adapter->rx_ring->itr_val = new_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
		if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
			adapter->rx_ring->set_itr = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
			ew32(ITR, 1000000000 / (new_itr * 256));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
 * e1000_alloc_queues - Allocate memory for all rings
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
 * @adapter: board private structure to initialize
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
	adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	if (!adapter->tx_ring)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
	adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	if (!adapter->rx_ring)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
err:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
	e_err("Unable to allocate memory for queues\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
	kfree(adapter->rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	kfree(adapter->tx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	return -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
 * e1000_clean - NAPI Rx polling callback
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
 * @napi: struct associated with this polling callback
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
 * @budget: amount of packets driver is allowed to process this poll
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
static int e1000_clean(struct napi_struct *napi, int budget)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
	struct net_device *poll_dev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	int tx_cleaned = 1, work_done = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	adapter = netdev_priv(poll_dev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	if (adapter->msix_entries &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
	    !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
		goto clean_rx;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	tx_cleaned = e1000_clean_tx_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
clean_rx:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
	adapter->clean_rx(adapter, &work_done, budget);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	if (!tx_cleaned)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
		work_done = budget;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	/* If budget not fully consumed, exit the polling mode */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
	if (work_done < budget) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
		if (adapter->itr_setting & 3)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
			e1000_set_itr(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
		napi_complete(napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
			if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
				ew32(IMS, adapter->rx_ring->ims_val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
			else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
				e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
	return work_done;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
	u32 vfta, index;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
	/* don't update vlan cookie if already programmed */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
	    (vid == adapter->mng_vlan_id))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
	/* add VID to filter table */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		index = (vid >> 5) & 0x7F;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
		vfta |= (1 << (vid & 0x1F));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
		hw->mac.ops.write_vfta(hw, index, vfta);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	u32 vfta, index;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
		e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
		e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
	    (vid == adapter->mng_vlan_id)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
		/* release control to f/w */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
	/* remove VID from filter table */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
		index = (vid >> 5) & 0x7F;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
		vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
		vfta &= ~(1 << (vid & 0x1F));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
		hw->mac.ops.write_vfta(hw, index, vfta);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	u16 vid = adapter->hw.mng_cookie.vlan_id;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
	u16 old_vid = adapter->mng_vlan_id;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	if (!adapter->vlgrp)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	if (!vlan_group_get_device(adapter->vlgrp, vid)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
		adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
		if (adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
			e1000_vlan_rx_add_vid(netdev, vid);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
			adapter->mng_vlan_id = vid;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
				(vid != old_vid) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		    !vlan_group_get_device(adapter->vlgrp, old_vid))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
			e1000_vlan_rx_kill_vid(netdev, old_vid);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
		adapter->mng_vlan_id = vid;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
static void e1000_vlan_rx_register(struct net_device *netdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
				   struct vlan_group *grp)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
	u32 ctrl, rctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
		e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	adapter->vlgrp = grp;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
	if (grp) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
		/* enable VLAN tag insert/strip */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
		ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
		ctrl |= E1000_CTRL_VME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
		ew32(CTRL, ctrl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
			/* enable VLAN receive filtering */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
			rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
			rctl &= ~E1000_RCTL_CFIEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
			ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
			e1000_update_mng_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
		/* disable VLAN tag insert/strip */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
		ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
		ctrl &= ~E1000_CTRL_VME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
		ew32(CTRL, ctrl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
			if (adapter->mng_vlan_id !=
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
			    (u16)E1000_MNG_VLAN_NONE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
				e1000_vlan_rx_kill_vid(netdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
						       adapter->mng_vlan_id);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
		e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
static void e1000_restore_vlan(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	u16 vid;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
	if (!adapter->vlgrp)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
		if (!vlan_group_get_device(adapter->vlgrp, vid))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
			continue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
		e1000_vlan_rx_add_vid(adapter->netdev, vid);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
static void e1000_init_manageability(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	u32 manc, manc2h;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
	manc = er32(MANC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	 * enable receiving management packets to the host. this will probably
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
	 * generate destination unreachable messages from the host OS, but
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
	 * the packets will be handled on SMBUS
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
	manc |= E1000_MANC_EN_MNG2HOST;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
	manc2h = er32(MANC2H);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
#define E1000_MNG2HOST_PORT_623 (1 << 5)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
#define E1000_MNG2HOST_PORT_664 (1 << 6)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
	manc2h |= E1000_MNG2HOST_PORT_623;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	manc2h |= E1000_MNG2HOST_PORT_664;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
	ew32(MANC2H, manc2h);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
	ew32(MANC, manc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
 * Configure the Tx unit of the MAC after a reset.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
static void e1000_configure_tx(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	u64 tdba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
	u32 tdlen, tctl, tipg, tarc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
	u32 ipgr1, ipgr2;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	/* Setup the HW Tx Head and Tail descriptor pointers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	tdba = tx_ring->dma;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	tdlen = tx_ring->count * sizeof(struct e1000_tx_desc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	ew32(TDBAH, (tdba >> 32));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	ew32(TDLEN, tdlen);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	ew32(TDH, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	ew32(TDT, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	tx_ring->head = E1000_TDH;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	tx_ring->tail = E1000_TDT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	/* Set the default values for the Tx Inter Packet Gap timer */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	tipg = DEFAULT_82543_TIPG_IPGT_COPPER;          /*  8  */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	ipgr1 = DEFAULT_82543_TIPG_IPGR1;               /*  8  */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	ipgr2 = DEFAULT_82543_TIPG_IPGR2;               /*  6  */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
	if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /*  7  */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	ew32(TIPG, tipg);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	/* Set the Tx Interrupt Delay register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	ew32(TIDV, adapter->tx_int_delay);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	/* Tx irq moderation */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	ew32(TADV, adapter->tx_abs_int_delay);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	/* Program the Transmit Control Register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	tctl = er32(TCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
	tctl &= ~E1000_TCTL_CT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
		tarc = er32(TARC(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
		 * set the speed mode bit, we'll clear it if we're not at
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		 * gigabit link later
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
#define SPEED_MODE_BIT (1 << 21)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
		tarc |= SPEED_MODE_BIT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
		ew32(TARC(0), tarc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2328
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2329
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	/* errata: program both queues to unweighted RR */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		tarc = er32(TARC(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
		tarc |= 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
		ew32(TARC(0), tarc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2335
		tarc = er32(TARC(1));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2336
		tarc |= 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
		ew32(TARC(1), tarc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2339
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
	/* Setup Transmit Descriptor Settings for eop descriptor */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2342
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
	/* only set IDE if we are delaying interrupts using the timers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
	if (adapter->tx_int_delay)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
	/* enable Report Status bit */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2349
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2350
	ew32(TCTL, tctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	e1000e_config_collision_dist(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	adapter->tx_queue_len = adapter->netdev->tx_queue_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
 * e1000_setup_rctl - configure the receive control registers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
 * @adapter: Board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
static void e1000_setup_rctl(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	u32 rctl, rfctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
	u32 psrctl = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
	u32 pages = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2369
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2370
	/* Program MC offset vector base */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2373
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2374
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2375
		(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2376
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2377
	/* Do not Store bad packets */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
	rctl &= ~E1000_RCTL_SBP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2380
	/* Enable Long Packet receive */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2381
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
		rctl &= ~E1000_RCTL_LPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2383
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2384
		rctl |= E1000_RCTL_LPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2385
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2386
	/* Some systems expect that the CRC is included in SMBUS traffic. The
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	 * hardware strips the CRC before sending to both SMBUS (BMC) and to
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2388
	 * host memory when this is enabled
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		rctl |= E1000_RCTL_SECRC;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2392
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2393
	/* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
	if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
		u16 phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		phy_data &= 0xfff8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2399
		phy_data |= (1 << 2);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2400
		e1e_wphy(hw, PHY_REG(770, 26), phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
		e1e_rphy(hw, 22, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
		phy_data &= 0x0fff;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		phy_data |= (1 << 14);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
		e1e_wphy(hw, 0x10, 0x2823);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
		e1e_wphy(hw, 0x11, 0x0003);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		e1e_wphy(hw, 22, phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2408
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2409
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
	/* Setup buffer sizes */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
	rctl &= ~E1000_RCTL_SZ_4096;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
	rctl |= E1000_RCTL_BSEX;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
	switch (adapter->rx_buffer_len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
	case 2048:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
		rctl |= E1000_RCTL_SZ_2048;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
		rctl &= ~E1000_RCTL_BSEX;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
	case 4096:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
		rctl |= E1000_RCTL_SZ_4096;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
	case 8192:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
		rctl |= E1000_RCTL_SZ_8192;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
	case 16384:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
		rctl |= E1000_RCTL_SZ_16384;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2430
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
	 * 82571 and greater support packet-split where the protocol
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
	 * header is placed in skb->data and the packet data is
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
	 * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
	 * In the case of a non-split, skb->data is linearly filled,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2435
	 * followed by the page buffers.  Therefore, skb->data is
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
	 * sized to hold the largest protocol header.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2438
	 * allocations using alloc_page take too long for regular MTU
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
	 * so only enable packet split for jumbo frames
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2440
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	 * Using pages when the page size is greater than 16k wastes
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	 * a lot of memory, since we allocate 3 pages at all times
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2443
	 * per packet.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
	    (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		adapter->rx_ps_pages = pages;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		adapter->rx_ps_pages = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2451
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2452
	if (adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2453
		/* Configure extra packet-split registers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2454
		rfctl = er32(RFCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2455
		rfctl |= E1000_RFCTL_EXTEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2456
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		 * disable packet split support for IPv6 extension headers,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2458
		 * because some malformed IPv6 headers can hang the Rx
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2460
		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
			  E1000_RFCTL_NEW_IPV6_EXT_DIS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
		ew32(RFCTL, rfctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
		/* Enable Packet split descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
		rctl |= E1000_RCTL_DTYP_PS;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2467
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2468
		psrctl |= adapter->rx_ps_bsize0 >>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
			E1000_PSRCTL_BSIZE0_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2470
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2471
		switch (adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
		case 3:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
			psrctl |= PAGE_SIZE <<
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
				E1000_PSRCTL_BSIZE3_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
		case 2:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
			psrctl |= PAGE_SIZE <<
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
				E1000_PSRCTL_BSIZE2_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
		case 1:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
			psrctl |= PAGE_SIZE >>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
				E1000_PSRCTL_BSIZE1_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2482
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2483
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2484
		ew32(PSRCTL, psrctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2485
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2486
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	/* just started the receive unit, no need to restart */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	adapter->flags &= ~FLAG_RX_RESTART_NOW;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
 * e1000_configure_rx - Configure Receive Unit after Reset
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2495
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2496
 * Configure the Rx unit of the MAC after a reset.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2497
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
static void e1000_configure_rx(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
	struct e1000_ring *rx_ring = adapter->rx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
	u64 rdba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2503
	u32 rdlen, rctl, rxcsum, ctrl_ext;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2504
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2505
	if (adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2506
		/* this is a 32 byte descriptor */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
		rdlen = rx_ring->count *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
			sizeof(union e1000_rx_desc_packet_split);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		adapter->clean_rx = e1000_clean_rx_irq_ps;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2510
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2515
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2516
		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2517
		adapter->clean_rx = e1000_clean_rx_irq;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
	/* disable receives while setting up the descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
	rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
	msleep(10);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
	/* set the Receive Delay Timer Register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
	ew32(RDTR, adapter->rx_int_delay);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2529
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
	/* irq moderation */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
	ew32(RADV, adapter->rx_abs_int_delay);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2532
	if (adapter->itr_setting != 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
		ew32(ITR, 1000000000 / (adapter->itr * 256));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2534
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2535
	ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
	/* Auto-Mask interrupts upon ICR access */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
	ctrl_ext |= E1000_CTRL_EXT_IAME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	ew32(IAM, 0xffffffff);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
	ew32(CTRL_EXT, ctrl_ext);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2541
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2542
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2543
	 * Setup the HW Rx Head and Tail Descriptor Pointers and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
	 * the Base and Length of the Rx Descriptor Ring
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2545
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2546
	rdba = rx_ring->dma;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2547
	ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2548
	ew32(RDBAH, (rdba >> 32));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
	ew32(RDLEN, rdlen);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2550
	ew32(RDH, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2551
	ew32(RDT, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2552
	rx_ring->head = E1000_RDH;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2553
	rx_ring->tail = E1000_RDT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2554
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
	/* Enable Receive Checksum Offload for TCP and UDP */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
	rxcsum = er32(RXCSUM);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2557
	if (adapter->flags & FLAG_RX_CSUM_ENABLED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2558
		rxcsum |= E1000_RXCSUM_TUOFL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2559
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2560
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2561
		 * IPv4 payload checksum for UDP fragments must be
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
		 * used in conjunction with packet-split.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2563
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2564
		if (adapter->rx_ps_pages)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
			rxcsum |= E1000_RXCSUM_IPPCSE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2566
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
		rxcsum &= ~E1000_RXCSUM_TUOFL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
		/* no need to clear IPPCSE as it defaults to 0 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2569
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2570
	ew32(RXCSUM, rxcsum);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2571
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2572
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2573
	 * Enable early receives on supported devices, only takes effect when
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2574
	 * packet size is equal or larger than the specified value (in 8 byte
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	if (adapter->flags & FLAG_HAS_ERT) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
			u32 rxdctl = er32(RXDCTL(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
			ew32(RXDCTL(0), rxdctl | 0x3);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
			ew32(ERT, E1000_ERT_2048 | (1 << 13));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2582
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2583
			 * With jumbo frames and early-receive enabled,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
			 * excessive C-state transition latencies result in
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
			 * dropped transactions.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2586
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2587
			pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
						  adapter->netdev->name, 55);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
			pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
						  adapter->netdev->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
						  PM_QOS_DEFAULT_VALUE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
	/* Enable Receives */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
	ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2598
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2599
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2600
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2601
 *  e1000_update_mc_addr_list - Update Multicast addresses
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
 *  @hw: pointer to the HW structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
 *  @mc_addr_list: array of multicast addresses to program
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
 *  @mc_addr_count: number of multicast addresses to program
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2605
 *  @rar_used_count: the first RAR register free to program
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
 *  @rar_count: total number of supported Receive Address Registers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2607
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2608
 *  Updates the Receive Address Registers and Multicast Table Array.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
 *  The caller must have a packed mc_addr_list of multicast addresses.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
 *  The parameter rar_count will usually be hw->mac.rar_entry_count
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
 *  unless there are workarounds that change this.  Currently no func pointer
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2612
 *  exists and all implementations are handled in the generic version of this
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
 *  function.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2615
static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
				      u32 mc_addr_count, u32 rar_used_count,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
				      u32 rar_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2618
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2619
	hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2620
				        rar_used_count, rar_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2623
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2624
 * e1000_set_multi - Multicast and Promiscuous mode set
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2625
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2626
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
 * The set_multi entry point is called whenever the multicast address
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2628
 * list or the network interface flags are updated.  This routine is
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
 * responsible for configuring the hardware for proper multicast,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
 * promiscuous mode, and all-multi behavior.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2631
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2632
static void e1000_set_multi(struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2633
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2636
	struct e1000_mac_info *mac = &hw->mac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	struct dev_mc_list *mc_ptr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
	u8  *mta_list;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	u32 rctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2641
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2642
	/* Check for Promiscuous and All Multicast modes */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2646
	if (netdev->flags & IFF_PROMISC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
		rctl &= ~E1000_RCTL_VFE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2650
		if (netdev->flags & IFF_ALLMULTI) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
			rctl |= E1000_RCTL_MPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
			rctl &= ~E1000_RCTL_UPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2653
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2654
			rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2655
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2657
			rctl |= E1000_RCTL_VFE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2660
	ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2662
	if (netdev->mc_count) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
		mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
		if (!mta_list)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
			return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2666
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
		/* prepare a packed array of only addresses. */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2668
		mc_ptr = netdev->mc_list;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2669
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
		for (i = 0; i < netdev->mc_count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2671
			if (!mc_ptr)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
			memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
			       ETH_ALEN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
			mc_ptr = mc_ptr->next;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2678
		e1000_update_mc_addr_list(hw, mta_list, i, 1,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
					  mac->rar_entry_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
		kfree(mta_list);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2682
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
		 * if we're called from probe, we might not have
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2684
		 * anything to do here, so clear out the list
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2685
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2686
		e1000_update_mc_addr_list(hw, NULL, 0, 1, mac->rar_entry_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2687
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2688
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2689
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2690
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2691
 * e1000_configure - configure the hardware for Rx and Tx
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2692
 * @adapter: private board structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2694
static void e1000_configure(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
	e1000_set_multi(adapter->netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	e1000_restore_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
	e1000_init_manageability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2701
	e1000_configure_tx(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
	e1000_setup_rctl(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2703
	e1000_configure_rx(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2704
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2705
	if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2706
		adapter->alloc_rx_buf(adapter, adapter->rx_ring->count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2707
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
		adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2711
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2713
 * e1000e_power_up_phy - restore link in case the phy was powered down
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2716
 * The phy may be powered down to save power and turn off link when the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2717
 * driver is unloaded and wake on lan is not enabled (among others)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
 * *** this routine MUST be followed by a call to e1000e_reset ***
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
void e1000e_power_up_phy(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2722
	if (adapter->hw.phy.ops.power_up)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		adapter->hw.phy.ops.power_up(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2724
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
	adapter->hw.mac.ops.setup_link(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2726
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2727
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2728
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2729
 * e1000_power_down_phy - Power down the PHY
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2730
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2731
 * Power down the PHY so no link is implied when interface is down.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2732
 * The PHY cannot be powered down if management or WoL is active.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
static void e1000_power_down_phy(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
	/* WoL is enabled */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
	if (adapter->wol)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2739
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
	if (adapter->hw.phy.ops.power_down)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
		adapter->hw.phy.ops.power_down(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
 * e1000e_reset - bring the hardware into a known good state
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2746
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2747
 * This function boots the hardware and enables some settings that
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
 * require a configuration cycle of the hardware - those cannot be
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
 * set/changed during runtime. After reset the device needs to be
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
 * properly configured for Rx, Tx etc.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2751
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2752
void e1000e_reset(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2753
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2754
	struct e1000_mac_info *mac = &adapter->hw.mac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2755
	struct e1000_fc_info *fc = &adapter->hw.fc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2756
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	u32 tx_space, min_tx_space, min_rx_space;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	u32 pba = adapter->pba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2759
	u16 hwm;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2760
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2761
	/* reset Packet Buffer Allocation to default */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	ew32(PBA, pba);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2763
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2764
	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2765
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2766
		 * To maintain wire speed transmits, the Tx FIFO should be
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		 * large enough to accommodate two full transmit packets,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
		 * the Rx FIFO should be large enough to accommodate at least
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
		 * one full receive packet and is similarly rounded up and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
		 * expressed in KB.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		pba = er32(PBA);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
		/* upper 16 bits has Tx packet buffer allocation size in KB */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		tx_space = pba >> 16;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		/* lower 16 bits has Rx packet buffer allocation size in KB */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
		pba &= 0xffff;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		 * the Tx fifo also stores 16 bytes of information about the tx
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
		 * but don't include ethernet FCS because hardware appends it
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
		min_tx_space = (adapter->max_frame_size +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
				sizeof(struct e1000_tx_desc) -
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2784
				ETH_FCS_LEN) * 2;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
		min_tx_space = ALIGN(min_tx_space, 1024);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
		min_tx_space >>= 10;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
		/* software strips receive CRC, so leave room for it */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2788
		min_rx_space = adapter->max_frame_size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
		min_rx_space = ALIGN(min_rx_space, 1024);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		min_rx_space >>= 10;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
		 * If current Tx allocation is less than the min Tx FIFO size,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
		 * and the min Tx FIFO size is less than the current Rx FIFO
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2795
		 * allocation, take space away from current Rx allocation
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2796
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2797
		if ((tx_space < min_tx_space) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
		    ((min_tx_space - tx_space) < pba)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2799
			pba -= min_tx_space - tx_space;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2800
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2801
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
			 * if short on Rx space, Rx wins and must trump tx
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
			 * adjustment or use Early Receive if available
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
			if ((pba < min_rx_space) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
			    (!(adapter->flags & FLAG_HAS_ERT)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
				/* ERT enabled in e1000_configure_rx */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
				pba = min_rx_space;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2810
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2811
		ew32(PBA, pba);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2812
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2814
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2815
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
	 * flow control settings
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2818
	 * The high water mark must be low enough to fit one full frame
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
	 * (or the size used for early receive) above it in the Rx FIFO.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	 * Set it to the lower of:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	 * - 90% of the Rx FIFO size, and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
	 * - the full Rx FIFO size minus the early receive size (for parts
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2824
	 * - the full Rx FIFO size minus one full frame
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
	if (hw->mac.type == e1000_pchlan) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2828
		 * Workaround PCH LOM adapter hangs with certain network
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2829
		 * loads.  If hangs persist, try disabling Tx flow control.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2830
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2831
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2832
			fc->high_water = 0x3500;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
			fc->low_water  = 0x1500;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2834
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
			fc->high_water = 0x5000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
			fc->low_water  = 0x3000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
		if ((adapter->flags & FLAG_HAS_ERT) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
		    (adapter->netdev->mtu > ETH_DATA_LEN))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
			hwm = min(((pba << 10) * 9 / 10),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2842
				  ((pba << 10) - (E1000_ERT_2048 << 3)));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2844
			hwm = min(((pba << 10) * 9 / 10),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
				  ((pba << 10) - adapter->max_frame_size));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2846
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2847
		fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2848
		fc->low_water = fc->high_water - 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2849
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2850
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
		fc->pause_time = 0xFFFF;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		fc->pause_time = E1000_FC_PAUSE_TIME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	fc->send_xon = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
	fc->current_mode = fc->requested_mode;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
	/* Allow time for pending master requests to run */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	mac->ops.reset_hw(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2860
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
	 * For parts with AMT enabled, let the firmware know
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
	 * that the network interface is in control
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
	if (adapter->flags & FLAG_HAS_AMT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	ew32(WUC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
		e1e_wphy(&adapter->hw, BM_WUC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2872
	if (mac->ops.init_hw(hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
		e_err("Hardware Error\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
	/* additional part of the flow-control workaround above */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	if (hw->mac.type == e1000_pchlan)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
		ew32(FCRTV_PCH, 0x1000);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	e1000_update_mng_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2880
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2881
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
	ew32(VET, ETH_P_8021Q);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	e1000e_reset_adaptive(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	e1000_get_phy_info(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2888
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
		u16 phy_data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2890
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2891
		 * speed up time to link by disabling smart power down, ignore
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
		 * the return value of this function because there is nothing
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
		 * different we would do if it failed
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
		phy_data &= ~IGP02E1000_PM_SPD;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2898
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
int e1000e_up(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	/* DMA latency requirement to workaround early-receive/jumbo issue */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
	if (adapter->flags & FLAG_HAS_ERT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
		pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
		                       adapter->netdev->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2909
				       PM_QOS_DEFAULT_VALUE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2910
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2911
	/* hardware has been reset, we need to reload some things */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	e1000_configure(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2913
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	clear_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  2916
	if (!adapter->ecdev)
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
		napi_enable(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2918
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
		e1000_configure_msix(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2921
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	if (!adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
		e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
		netif_wake_queue(adapter->netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2926
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2927
		/* fire a link change interrupt to start the watchdog */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
		ew32(ICS, E1000_ICS_LSC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2929
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2932
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2933
void e1000e_down(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2934
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2935
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2936
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	u32 tctl, rctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2938
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2939
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2940
	 * signal that we're down so the interrupt handler does not
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	 * reschedule our watchdog timer
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2942
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2943
	set_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
	/* disable receives in the hardware */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
	/* flush and sleep below */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  2950
	if (!adapter->ecdev)
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
		netif_stop_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	/* disable transmits in the hardware */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
	tctl = er32(TCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
	tctl &= ~E1000_TCTL_EN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
	ew32(TCTL, tctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
	/* flush both disables and wait for them to finish */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
	msleep(10);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2960
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
	if (!adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2962
		napi_disable(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
		e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
		del_timer_sync(&adapter->watchdog_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
		del_timer_sync(&adapter->phy_info_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2967
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2968
		netdev->tx_queue_len = adapter->tx_queue_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
		netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	adapter->link_speed = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
	adapter->link_duplex = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
	if (!pci_channel_offline(adapter->pdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
		e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
	e1000_clean_tx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
	e1000_clean_rx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2979
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
	if (adapter->flags & FLAG_HAS_ERT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
		pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
		                          adapter->netdev->name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2984
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
	 * TODO: for power management, we could drop the link and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
	 * pci_disable_device here.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2988
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2989
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2990
void e1000e_reinit_locked(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
	might_sleep();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2994
		msleep(1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
	e1000e_up(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	clear_bit(__E1000_RESETTING, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2998
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3000
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3001
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
 * @adapter: board private structure to initialize
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
 * e1000_sw_init initializes the Adapter private data structure.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
 * Fields are initialized based on PCI device information and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3006
 * OS network device settings (MTU size).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3011
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3012
	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
	adapter->rx_ps_bsize0 = 128;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3017
	e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	if (e1000_alloc_queues(adapter))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
		return -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
	/* Explicitly disable IRQ since the NIC can be in any state. */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3024
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3025
	set_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3029
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3030
 * e1000_intr_msi_test - Interrupt Handler
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
 * @irq: interrupt number
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
 * @data: pointer to a network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3033
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3034
static irqreturn_t e1000_intr_msi_test(int irq, void *data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
	u32 icr = er32(ICR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	e_dbg("icr is %08X\n", icr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	if (icr & E1000_ICR_RXSEQ) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
		wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3045
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3046
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3047
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3048
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3049
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3050
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
 * e1000_test_msi_interrupt - Returns 0 for successful test
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3052
 * @adapter: board private struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
 * code flow taken from tg3.c
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3055
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3056
static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3060
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3061
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3062
	/* poll_enable hasn't been called yet, so don't need disable */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
	/* clear any pending events */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	er32(ICR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3065
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3066
	/* free the real vector and request a test handler */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	e1000_free_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3068
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	/* Assume that the test fails, if it succeeds then the test
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
	 * MSI irq handler will unset this flag */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
	adapter->flags |= FLAG_MSI_TEST_FAILED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	err = pci_enable_msi(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
		goto msi_test_failed;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
	err = request_irq(adapter->pdev->irq, e1000_intr_msi_test, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3079
			  netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
		pci_disable_msi(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
		goto msi_test_failed;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3083
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3084
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
	wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3086
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3087
	e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3089
	/* fire an unusual interrupt on the test handler */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
	ew32(ICS, E1000_ICS_RXSEQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3092
	msleep(50);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3094
	e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3095
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3096
	rmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3097
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3098
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3100
		err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
		e_info("MSI interrupt test failed!\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
	free_irq(adapter->pdev->irq, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	pci_disable_msi(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
	if (err == -EIO)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
		goto msi_test_failed;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
	/* okay so the test worked, restore settings */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	e_dbg("MSI interrupt test succeeded!\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
msi_test_failed:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
	e1000_request_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
 * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
 * @adapter: board private struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
 * code flow taken from tg3.c, called with e1000 interrupts disabled.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3124
static int e1000_test_msi(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
	u16 pci_cmd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3128
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3129
	if (!(adapter->flags & FLAG_MSI_ENABLED))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3130
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3131
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3132
	/* disable SERR in case the MSI write causes a master abort */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
	pci_write_config_word(adapter->pdev, PCI_COMMAND,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
			      pci_cmd & ~PCI_COMMAND_SERR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3137
	err = e1000_test_msi_interrupt(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3138
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3139
	/* restore previous setting of command word */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
	/* success ! */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
	/* EIO means MSI test failed */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	if (err != -EIO)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
		return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3149
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3150
	/* back to INTx mode */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	e_warn("MSI interrupt test failed, using legacy interrupt.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3153
	e1000_free_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
	err = e1000_request_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3158
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3159
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3160
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3161
 * e1000_open - Called when a network interface is made active
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
 * Returns 0 on success, negative value on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
 * The open entry point is called when a network interface is made
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
 * active by the system (IFF_UP).  At this point all resources needed
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
 * for transmit and receive operations are allocated, the interrupt
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
 * handler is registered with the OS, the watchdog timer is started,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3170
 * and the stack is notified that the interface is ready.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3171
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3172
static int e1000_open(struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3173
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3174
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
	/* disallow open during test */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	if (test_bit(__E1000_TESTING, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
		return -EBUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
	if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
		ecdev_set_link(adapter->ecdev, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
		netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3186
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3187
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
	/* allocate transmit descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
	err = e1000e_setup_tx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3191
		goto err_setup_tx;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3193
	/* allocate receive descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3194
	err = e1000e_setup_rx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3195
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3196
		goto err_setup_rx;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3198
	e1000e_power_up_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3202
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
		e1000_update_mng_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3205
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3206
	 * If AMT is enabled, let the firmware know that the network
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	 * interface is now open
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3208
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3209
	if (adapter->flags & FLAG_HAS_AMT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3211
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3212
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	 * before we allocate an interrupt, we must be ready to handle it.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	 * as soon as we call pci_request_irq, so we have to setup our
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	 * clean_rx handler before we do so.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3217
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3218
	e1000_configure(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3219
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3220
	err = e1000_request_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3221
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
		goto err_req_irq;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
	 * Work around PCIe errata with MSI interrupts causing some chipsets to
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	 * ignore e1000e MSI messages, which means we need to test our MSI
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
	 * interrupt now
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3228
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3229
	if (adapter->int_mode != E1000E_INT_MODE_LEGACY) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3230
		err = e1000_test_msi(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
		if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
			e_err("Interrupt allocation failed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
			goto err_req_irq;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3234
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3235
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3236
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	/* From here on the code is the same as e1000e_up() */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	clear_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3240
	if (!adapter->ecdev) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3241
		napi_enable(&adapter->napi);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3242
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3243
		e1000_irq_enable(adapter);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3244
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3245
		netif_start_queue(netdev);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3246
	}
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3247
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	/* fire a link status change interrupt to start the watchdog */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
	ew32(ICS, E1000_ICS_LSC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3251
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3252
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3253
err_req_irq:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3254
	e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3255
	e1000_power_down_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3256
	e1000e_free_rx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3257
err_setup_rx:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3258
	e1000e_free_tx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
err_setup_tx:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
	e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3263
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3264
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3265
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
 * e1000_close - Disables a network interface
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3268
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3269
 * Returns 0, this is not allowed to fail
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3270
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
 * The close entry point is called when an interface is de-activated
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
 * by the OS.  The hardware is still under the drivers control, but
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3273
 * needs to be disabled.  A global MAC reset is issued to stop the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3274
 * hardware, and all transmit and receive resources are freed.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3275
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
static int e1000_close(struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3277
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
	e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
	e1000_power_down_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
	e1000_free_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3285
	e1000e_free_tx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
	e1000e_free_rx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3288
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	 * kill manageability vlan ID if supported, but not if a vlan with
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3290
	 * the same ID is registered on the host OS (let 8021q kill it)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3291
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3292
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
	     !(adapter->vlgrp &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3295
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3298
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	 * If AMT is enabled, let the firmware know that the network
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	 * interface is now closed
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	if (adapter->flags & FLAG_HAS_AMT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
		e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3304
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3305
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3306
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3307
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3308
 * e1000_set_mac - Change the Ethernet Address of the NIC
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
 * @p: pointer to an address structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
 * Returns 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
static int e1000_set_mac(struct net_device *netdev, void *p)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	struct sockaddr *addr = p;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	if (!is_valid_ether_addr(addr->sa_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
		return -EADDRNOTAVAIL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3325
	e1000e_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3326
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
		/* activate the work around */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3329
		e1000e_set_laa_state_82571(&adapter->hw, 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3330
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3331
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3332
		 * Hold a copy of the LAA in RAR[14] This is done so that
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3333
		 * between the time RAR[0] gets clobbered  and the time it
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3334
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
		 * of the RARs and no incoming packets directed to this port
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		 * are dropped. Eventually the LAA will be in RAR[0] and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3337
		 * RAR[14]
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3338
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
		e1000e_rar_set(&adapter->hw,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
			      adapter->hw.mac.addr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3341
			      adapter->hw.mac.rar_entry_count - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3342
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
 * e1000e_update_phy_task - work thread to update phy
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
 * @work: pointer to our work struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
 * this worker thread exists because we must acquire a
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
 * semaphore to read the phy, which we could msleep while
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
 * waiting for it, and we can't msleep in a timer.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
static void e1000e_update_phy_task(struct work_struct *work)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
					struct e1000_adapter, update_phy_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
	e1000_get_phy_info(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3362
/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3363
 * Need to wait a few seconds after link up to get diagnostic information from
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
 * the phy
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
static void e1000_update_phy_info(unsigned long data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3367
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
	schedule_work(&adapter->update_phy_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3370
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3371
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
 * e1000e_update_stats - Update the board statistics counters
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
void e1000e_update_stats(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
	u16 phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3382
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3383
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	 * Prevent stats update while adapter is being reset, or if the pci
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
	 * connection is down.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
	if (adapter->link_speed == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	if (pci_channel_offline(pdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
	adapter->stats.crcerrs += er32(CRCERRS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	adapter->stats.gprc += er32(GPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	adapter->stats.gorc += er32(GORCL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	er32(GORCH); /* Clear gorc */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
	adapter->stats.bprc += er32(BPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	adapter->stats.mprc += er32(MPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
	adapter->stats.roc += er32(ROC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3399
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3400
	adapter->stats.mpc += er32(MPC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3401
	if ((hw->phy.type == e1000_phy_82578) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3402
	    (hw->phy.type == e1000_phy_82577)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
		e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
		if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
			adapter->stats.scc += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
		e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3408
		if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
			adapter->stats.ecol += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3410
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3411
		e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3412
		if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
			adapter->stats.mcc += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
		e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
		if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3417
			adapter->stats.latecol += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3418
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3419
		e1e_rphy(hw, HV_DC_UPPER, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
		if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
			adapter->stats.dc += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
		adapter->stats.scc += er32(SCC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
		adapter->stats.ecol += er32(ECOL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
		adapter->stats.mcc += er32(MCC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
		adapter->stats.latecol += er32(LATECOL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
		adapter->stats.dc += er32(DC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3428
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3429
	adapter->stats.xonrxc += er32(XONRXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3430
	adapter->stats.xontxc += er32(XONTXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
	adapter->stats.xoffrxc += er32(XOFFRXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
	adapter->stats.xofftxc += er32(XOFFTXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3433
	adapter->stats.gptc += er32(GPTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	adapter->stats.gotc += er32(GOTCL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	er32(GOTCH); /* Clear gotc */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3436
	adapter->stats.rnbc += er32(RNBC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
	adapter->stats.ruc += er32(RUC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	adapter->stats.mptc += er32(MPTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3440
	adapter->stats.bptc += er32(BPTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3441
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3442
	/* used for adaptive IFS */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3443
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3444
	hw->mac.tx_packet_delta = er32(TPT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3445
	adapter->stats.tpt += hw->mac.tx_packet_delta;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3446
	if ((hw->phy.type == e1000_phy_82578) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3447
	    (hw->phy.type == e1000_phy_82577)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3448
		e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
		if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
			hw->mac.collision_delta = phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		hw->mac.collision_delta = er32(COLC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3453
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
	adapter->stats.colc += hw->mac.collision_delta;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3456
	adapter->stats.algnerrc += er32(ALGNERRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3457
	adapter->stats.rxerrc += er32(RXERRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
	if ((hw->phy.type == e1000_phy_82578) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
	    (hw->phy.type == e1000_phy_82577)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3460
		e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
		if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
			adapter->stats.tncrs += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		if ((hw->mac.type != e1000_82574) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		    (hw->mac.type != e1000_82583))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3466
			adapter->stats.tncrs += er32(TNCRS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3467
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3468
	adapter->stats.cexterr += er32(CEXTERR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
	adapter->stats.tsctc += er32(TSCTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3470
	adapter->stats.tsctfc += er32(TSCTFC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	/* Fill out the OS statistics structure */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
	netdev->stats.multicast = adapter->stats.mprc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	netdev->stats.collisions = adapter->stats.colc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3475
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3476
	/* Rx Errors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	 * RLEC on some newer hardware can be incorrect so build
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	 * our own version based on RUC and ROC
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3482
	netdev->stats.rx_errors = adapter->stats.rxerrc +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
		adapter->stats.crcerrs + adapter->stats.algnerrc +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
		adapter->stats.ruc + adapter->stats.roc +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
		adapter->stats.cexterr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
	netdev->stats.rx_length_errors = adapter->stats.ruc +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
					      adapter->stats.roc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3488
	netdev->stats.rx_crc_errors = adapter->stats.crcerrs;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	netdev->stats.rx_frame_errors = adapter->stats.algnerrc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
	netdev->stats.rx_missed_errors = adapter->stats.mpc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
	/* Tx Errors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	netdev->stats.tx_errors = adapter->stats.ecol +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
				       adapter->stats.latecol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3495
	netdev->stats.tx_aborted_errors = adapter->stats.ecol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3496
	netdev->stats.tx_window_errors = adapter->stats.latecol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3497
	netdev->stats.tx_carrier_errors = adapter->stats.tncrs;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3498
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3499
	/* Tx Dropped needs to be maintained elsewhere */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
	/* Management Stats */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
	adapter->stats.mgptc += er32(MGTPTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3503
	adapter->stats.mgprc += er32(MGTPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
	adapter->stats.mgpdc += er32(MGTPDC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3506
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3507
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
 * e1000_phy_read_status - Update the PHY register status snapshot
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3510
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
static void e1000_phy_read_status(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3514
	struct e1000_phy_regs *phy = &adapter->phy_regs;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3515
	int ret_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	if ((er32(STATUS) & E1000_STATUS_LU) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
		ret_val  = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
		ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3522
		ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
		ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3525
		ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
		ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
		if (ret_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
			e_warn("Error reading PHY register\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3531
		 * Do not read PHY registers if link is not up
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
		 * Set values to typical power-on defaults
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
			     BMSR_ERCAP);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
				  ADVERTISE_ALL | ADVERTISE_CSMA);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
		phy->lpa = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
		phy->expansion = EXPANSION_ENABLENPAGE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
		phy->ctrl1000 = ADVERTISE_1000FULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
		phy->stat1000 = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3545
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3547
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3548
static void e1000_print_link_info(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3549
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	u32 ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3552
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3553
	/* Link status message must follow this format for user tools */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
	printk(KERN_INFO "e1000e: %s NIC Link is Up %d Mbps %s, "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
	       "Flow Control: %s\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
	       adapter->netdev->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3557
	       adapter->link_speed,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	       (adapter->link_duplex == FULL_DUPLEX) ?
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
	                        "Full Duplex" : "Half Duplex",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	       ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	                        "RX/TX" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3562
	       ((ctrl & E1000_CTRL_RFCE) ? "RX" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3563
	       ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3564
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
bool e1000_has_link(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3567
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3568
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	bool link_active = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
	s32 ret_val = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3572
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3573
	 * get_link_status is set on LSC (link status) interrupt or
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	 * Rx sequence error interrupt.  get_link_status will stay
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	 * false until the check_for_link establishes link
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3576
	 * for copper adapters ONLY
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3577
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3578
	switch (hw->phy.media_type) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
	case e1000_media_type_copper:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
		if (hw->mac.get_link_status) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
			ret_val = hw->mac.ops.check_for_link(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
			link_active = !hw->mac.get_link_status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3584
			link_active = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
	case e1000_media_type_fiber:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
		ret_val = hw->mac.ops.check_for_link(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3589
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3590
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
	case e1000_media_type_internal_serdes:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3592
		ret_val = hw->mac.ops.check_for_link(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
		link_active = adapter->hw.mac.serdes_has_link;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
	case e1000_media_type_unknown:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3598
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3599
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3600
	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3602
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
		e_info("Gigabit has been disabled, downgrading speed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
	return link_active;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3607
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3608
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3609
static void e1000e_enable_receives(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3610
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
	/* make sure the receive unit is started */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3613
	    (adapter->flags & FLAG_RX_RESTART_NOW)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
		struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
		u32 rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
		ew32(RCTL, rctl | E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
		adapter->flags &= ~FLAG_RX_RESTART_NOW;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
 * e1000_watchdog - Timer Call-back
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
 * @data: pointer to adapter cast into an unsigned long
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
static void e1000_watchdog(unsigned long data)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3626
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3627
	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
	/* Do the rest outside of interrupt context */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
	schedule_work(&adapter->watchdog_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3632
	/* TODO: make this use queue_delayed_work() */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
static void e1000_watchdog_task(struct work_struct *work)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
					struct e1000_adapter, watchdog_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
	struct e1000_mac_info *mac = &adapter->hw.mac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3641
	struct e1000_phy_info *phy = &adapter->hw.phy;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
	u32 link, tctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
	int tx_pending = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
	link = e1000_has_link(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3648
	if ((adapter->ecdev && (ecdev_get_link(adapter->ecdev)) && link)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
			|| (!adapter->ecdev && (netif_carrier_ok(netdev)) && link)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
		e1000e_enable_receives(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
		goto link_up;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
		e1000_update_mng_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
	if (link) {
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3659
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
			bool txb2b = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
			/* update snapshot of PHY registers on LSC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3663
			e1000_phy_read_status(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
			mac->ops.get_link_up_info(&adapter->hw,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
						   &adapter->link_speed,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
						   &adapter->link_duplex);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
			e1000_print_link_info(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3668
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3669
			 * On supported PHYs, check for duplex mismatch only
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
			 * if link has autonegotiated at 10/100 half
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
			if ((hw->phy.type == e1000_phy_igp_3 ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
			     hw->phy.type == e1000_phy_bm) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
			    (hw->mac.autoneg == true) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
			    (adapter->link_speed == SPEED_10 ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
			     adapter->link_speed == SPEED_100) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
			    (adapter->link_duplex == HALF_DUPLEX)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
				u16 autoneg_exp;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
				e1e_rphy(hw, PHY_AUTONEG_EXP, &autoneg_exp);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3681
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3682
				if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
					e_info("Autonegotiated half duplex but"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
					       " link partner cannot autoneg. "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
					       " Try forcing full duplex if "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
					       "link gets many collisions.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3688
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
			 * tweak tx_queue_len according to speed/duplex
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
			 * and adjust the timeout factor
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
			netdev->tx_queue_len = adapter->tx_queue_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
			adapter->tx_timeout_factor = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
			switch (adapter->link_speed) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
			case SPEED_10:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
				txb2b = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
				netdev->tx_queue_len = 10;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
				adapter->tx_timeout_factor = 16;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
			case SPEED_100:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
				txb2b = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3703
				netdev->tx_queue_len = 100;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
				adapter->tx_timeout_factor = 10;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3705
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3706
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3707
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3708
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
			 * workaround: re-program speed mode bit after
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3710
			 * link-up event
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3711
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3712
			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
			    !txb2b) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
				u32 tarc0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
				tarc0 = er32(TARC(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3716
				tarc0 &= ~SPEED_MODE_BIT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
				ew32(TARC(0), tarc0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3718
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3719
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3720
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3721
			 * disable TSO for pcie and 10/100 speeds, to avoid
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3722
			 * some hardware issues
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3723
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3724
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
				switch (adapter->link_speed) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
				case SPEED_10:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
				case SPEED_100:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
					e_info("10/100 speed: disabling TSO\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
					netdev->features &= ~NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
					netdev->features &= ~NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
					break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3732
				case SPEED_1000:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
					netdev->features |= NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
					netdev->features |= NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
					break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
				default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
					/* oops */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3738
					break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3739
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3740
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3741
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3742
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3743
			 * enable transmits in the hardware, need to do this
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
			 * after setting TARC(0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3746
			tctl = er32(TCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
			tctl |= E1000_TCTL_EN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
			ew32(TCTL, tctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
                        /*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
			 * Perform any post-link-up configuration before
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
			 * reporting link up.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
			if (phy->ops.cfg_on_link_up)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
				phy->ops.cfg_on_link_up(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
			if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
				ecdev_set_link(adapter->ecdev, 1);
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3759
			else
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
				netif_carrier_on(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3761
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
			if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
				mod_timer(&adapter->phy_info_timer,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3764
					  round_jiffies(jiffies + 2 * HZ));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	} else {
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3767
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
			adapter->link_speed = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
			adapter->link_duplex = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
			/* Link status message must follow this format */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
			printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
			       adapter->netdev->name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
			if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
				ecdev_set_link(adapter->ecdev, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
			else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3777
				netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
			if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
				mod_timer(&adapter->phy_info_timer,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
					  round_jiffies(jiffies + 2 * HZ));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3782
			if (adapter->flags & FLAG_RX_NEEDS_RESTART)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
				schedule_work(&adapter->reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
link_up:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3788
	e1000e_update_stats(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	adapter->tpt_old = adapter->stats.tpt;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
	adapter->colc_old = adapter->stats.colc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3794
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
	adapter->gorc_old = adapter->stats.gorc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	adapter->gotc_old = adapter->stats.gotc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3800
	e1000e_update_adaptive(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  3802
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
		tx_pending = (e1000_desc_unused(tx_ring) + 1 <
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
			       tx_ring->count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3805
		if (tx_pending) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3806
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
			 * We've lost link, so the controller stops DMA,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
			 * but we've got queued Tx work that's never going
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3809
			 * to get done, so reset controller to flush Tx.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
			 * (Do the reset outside of interrupt context).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3812
			adapter->tx_timeout_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3813
			schedule_work(&adapter->reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3814
			/* return immediately since reset is imminent */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3815
			return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3816
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3817
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3818
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3819
	/* Cause software interrupt to ensure Rx ring is cleaned */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3820
	if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
		ew32(ICS, adapter->rx_ring->ims_val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
		ew32(ICS, E1000_ICS_RXDMT0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
	/* Force detection of hung controller every watchdog period */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
	adapter->detect_tx_hung = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3828
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3829
	 * With 82571 controllers, LAA may be overwritten due to controller
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
	 * reset from the other port. Set the appropriate LAA in RAR[0]
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3831
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3832
	if (e1000e_get_laa_state_82571(hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3833
		e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3835
	/* Reset the timer */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	if (!adapter->ecdev && !test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
		mod_timer(&adapter->watchdog_timer,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
			  round_jiffies(jiffies + 2 * HZ));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
#define E1000_TX_FLAGS_CSUM		0x00000001
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
#define E1000_TX_FLAGS_VLAN		0x00000002
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
#define E1000_TX_FLAGS_TSO		0x00000004
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
#define E1000_TX_FLAGS_IPV4		0x00000008
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3846
#define E1000_TX_FLAGS_VLAN_SHIFT	16
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3847
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
static int e1000_tso(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
		     struct sk_buff *skb)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
	struct e1000_context_desc *context_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
	u32 cmd_length = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
	u16 ipcse = 0, tucse, mss;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	if (!skb_is_gso(skb))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
	if (skb_header_cloned(skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
		if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
			return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3868
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3869
	hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	mss = skb_shinfo(skb)->gso_size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	if (skb->protocol == htons(ETH_P_IP)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3872
		struct iphdr *iph = ip_hdr(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
		iph->tot_len = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
		iph->check = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3875
		tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
		                                         0, IPPROTO_TCP, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
		cmd_length = E1000_TXD_CMD_IP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3878
		ipcse = skb_transport_offset(skb) - 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	} else if (skb_is_gso_v6(skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3880
		ipv6_hdr(skb)->payload_len = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
		tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
		                                       &ipv6_hdr(skb)->daddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
		                                       0, IPPROTO_TCP, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
		ipcse = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
	ipcss = skb_network_offset(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
	tucss = skb_transport_offset(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
	tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
	tucse = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3891
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3892
	cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
	               E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3894
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3895
	i = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3896
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
	buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3898
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
	context_desc->lower_setup.ip_fields.ipcss  = ipcss;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	context_desc->lower_setup.ip_fields.ipcso  = ipcso;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3901
	context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	context_desc->upper_setup.tcp_fields.tucss = tucss;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	context_desc->upper_setup.tcp_fields.tucso = tucso;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3905
	context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
	context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	context_desc->cmd_and_length = cpu_to_le32(cmd_length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3908
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3909
	buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
	buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
	i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
	if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
	tx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3917
	return 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3920
static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3921
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3922
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
	struct e1000_context_desc *context_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
	u8 css;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
	u32 cmd_len = E1000_TXD_CMD_DEXT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
	__be16 protocol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
	if (skb->ip_summed != CHECKSUM_PARTIAL)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3932
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3933
	if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		protocol = skb->protocol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
	switch (protocol) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
	case cpu_to_be16(ETH_P_IP):
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
			cmd_len |= E1000_TXD_CMD_TCP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
	case cpu_to_be16(ETH_P_IPV6):
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
		/* XXX not handling all IPV6 headers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
			cmd_len |= E1000_TXD_CMD_TCP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
		if (unlikely(net_ratelimit()))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
			e_warn("checksum_partial proto=%x!\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
			       be16_to_cpu(protocol));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3952
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
	css = skb_transport_offset(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3956
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
	i = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
	buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
	context_desc->lower_setup.ip_config = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
	context_desc->upper_setup.tcp_fields.tucss = css;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
	context_desc->upper_setup.tcp_fields.tucso =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
				css + skb->csum_offset;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	context_desc->upper_setup.tcp_fields.tucse = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3966
	context_desc->tcp_seg_setup.data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3968
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3969
	buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3971
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
	i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
	if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
		i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	tx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
	return 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
#define E1000_MAX_PER_TXD	8192
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
#define E1000_MAX_TXD_PWR	12
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3982
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3983
static int e1000_tx_map(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
			struct sk_buff *skb, unsigned int first,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
			unsigned int max_per_txd, unsigned int nr_frags,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
			unsigned int mss)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3987
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3990
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
	unsigned int len = skb_headlen(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
	unsigned int offset = 0, size, count = 0, i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3993
	unsigned int f;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3994
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3995
	i = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3997
	while (len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
		size = min(len, max_per_txd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
		buffer_info->length = size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
		buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
		buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
		buffer_info->dma = pci_map_single(pdev,	skb->data + offset,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
						  size,	PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4006
		buffer_info->mapped_as_page = false;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
		if (pci_dma_mapping_error(pdev, buffer_info->dma))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
			goto dma_error;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
		len -= size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
		offset += size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4012
		count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4013
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4014
		if (len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
			i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
			if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
				i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4019
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4020
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
	for (f = 0; f < nr_frags; f++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4022
		struct skb_frag_struct *frag;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4023
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
		frag = &skb_shinfo(skb)->frags[f];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		len = frag->size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
		offset = frag->page_offset;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4027
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4028
		while (len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
			i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4030
			if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
				i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4033
			buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4034
			size = min(len, max_per_txd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
			buffer_info->length = size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
			buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
			buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
			buffer_info->dma = pci_map_page(pdev, frag->page,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
							offset, size,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4041
							PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
			buffer_info->mapped_as_page = true;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4043
			if (pci_dma_mapping_error(pdev, buffer_info->dma))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4044
				goto dma_error;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
			len -= size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
			offset += size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
			count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4050
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4051
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4052
	tx_ring->buffer_info[i].skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
	tx_ring->buffer_info[first].next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4054
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4055
	return count;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4057
dma_error:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
	dev_err(&pdev->dev, "TX DMA map failed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
	buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	if (count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
		count--;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
	while (count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
		if (i==0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
			i += tx_ring->count;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4066
		i--;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
		e1000_put_txbuf(adapter, buffer_info);;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4070
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
static void e1000_tx_queue(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
			   int tx_flags, int count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4076
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
	struct e1000_tx_desc *tx_desc = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4082
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
	if (tx_flags & E1000_TX_FLAGS_TSO) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
			     E1000_TXD_CMD_TSE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4088
		if (tx_flags & E1000_TX_FLAGS_IPV4)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4090
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4091
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4096
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
		txd_lower |= E1000_TXD_CMD_VLE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4101
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
	i = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4104
	while (count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
		tx_desc = E1000_TX_DESC(*tx_ring, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
		tx_desc->lower.data =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
			cpu_to_le32(txd_lower | buffer_info->length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
		tx_desc->upper.data = cpu_to_le32(txd_upper);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4111
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4112
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4113
		if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4115
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4116
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4117
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4119
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4120
	 * Force memory writes to complete before letting h/w
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
	 * know there are new descriptors to fetch.  (Only
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4122
	 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4123
	 * such as IA-64).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4124
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4125
	wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4127
	tx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
	writel(i, adapter->hw.hw_addr + tx_ring->tail);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4129
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4130
	 * we need this if more than one processor can write to our tail
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	 * at a time, it synchronizes IO on IA64/Altix systems
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4132
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	mmiowb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
#define MINIMUM_DHCP_PACKET_SIZE 282
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
				    struct sk_buff *skb)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
	struct e1000_hw *hw =  &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
	u16 length, offset;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4142
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4143
	if (vlan_tx_tag_present(skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
		    (adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
			return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4149
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4150
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4152
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4153
	if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4154
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4155
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4156
	{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4157
		const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
		struct udphdr *udp;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4160
		if (ip->protocol != IPPROTO_UDP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4161
			return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4162
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4163
		udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4164
		if (ntohs(udp->dest) != 67)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4165
			return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4166
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4167
		offset = (u8 *)udp + 8 - skb->data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4168
		length = skb->len - offset;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4170
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4171
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4175
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4176
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  4179
	if (adapter->ecdev) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  4180
		return -EBUSY;
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  4181
	}
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  4182
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	netif_stop_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4184
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4185
	 * Herbert's original patch had:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
	 *  smp_mb__after_netif_stop_queue();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
	 * but since that doesn't exist yet, just open code it.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
	smp_mb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4191
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	 * We need to check again in a case another CPU has just
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	 * made room available.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4195
	if (e1000_desc_unused(adapter->tx_ring) < size)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
		return -EBUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
	/* A reprieve! */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
	netif_start_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
	++adapter->restart_queue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4202
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4203
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4204
static int e1000_maybe_stop_tx(struct net_device *netdev, int size)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4208
	if (e1000_desc_unused(adapter->tx_ring) >= size)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4210
	return __e1000_maybe_stop_tx(netdev, size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4211
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4212
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
				    struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	struct e1000_ring *tx_ring = adapter->tx_ring;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
	unsigned int first;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	unsigned int max_per_txd = E1000_MAX_PER_TXD;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	unsigned int tx_flags = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
	unsigned int len = skb->len - skb->data_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
	unsigned int nr_frags;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	unsigned int mss;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	int count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4227
	int tso;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4228
	unsigned int f;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4229
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4230
	if (test_bit(__E1000_DOWN, &adapter->state)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
		if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
			dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
		return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4234
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4235
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
	if (skb->len <= 0) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
		if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4238
			dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4239
		return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
	mss = skb_shinfo(skb)->gso_size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4243
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	 * The controller does a simple calculation to
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
	 * make sure there is enough room in the FIFO before
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
	 * initiating the DMA for each buffer.  The calc is:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
	 * 4 = ceil(buffer len/mss).  To make sure we don't
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
	 * overrun the FIFO, adjust the max buffer len if mss
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
	 * drops.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4251
	if (mss) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
		u8 hdr_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
		max_per_txd = min(mss << 2, max_per_txd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4254
		max_txd_pwr = fls(max_per_txd) - 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4256
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4257
		 * TSO Workaround for 82571/2/3 Controllers -- if skb->data
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
		 * points to just header, pull a few bytes of payload from
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
		 * frags into skb->data
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4260
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4261
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4263
		 * we do this workaround for ES2LAN, but it is un-necessary,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
		 * avoiding it could save a lot of cycles
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4266
		if (skb->data_len && (hdr_len == len)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
			unsigned int pull_size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4268
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4269
			pull_size = min((unsigned int)4, skb->data_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
			if (!__pskb_pull_tail(skb, pull_size)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
				e_err("__pskb_pull_tail failed.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
				if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
					dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
				return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4275
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4276
			len = skb->len - skb->data_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4278
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	/* reserve a descriptor for the offload context */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
		count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
	count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4285
	count += TXD_USE_COUNT(len, max_txd_pwr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4287
	nr_frags = skb_shinfo(skb)->nr_frags;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
	for (f = 0; f < nr_frags; f++)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
				       max_txd_pwr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4291
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
	if (adapter->hw.mac.tx_pkt_filtering)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
		e1000_transfer_dhcp_info(adapter, skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4294
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	 * need: count + 2 desc gap to keep tail from touching
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4297
	 * head, otherwise try next time
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
	if (!adapter->ecdev && e1000_maybe_stop_tx(netdev, count + 2))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
		return NETDEV_TX_BUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4301
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4302
	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
		tx_flags |= E1000_TX_FLAGS_VLAN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4304
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	first = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4308
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4309
	tso = e1000_tso(adapter, skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4310
	if (tso < 0) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
		if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4312
			dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
		return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4314
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
	if (tso)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
		tx_flags |= E1000_TX_FLAGS_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	else if (e1000_tx_csum(adapter, skb))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
		tx_flags |= E1000_TX_FLAGS_CSUM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4320
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4321
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
	 * Old method was to assume IPv4 packet by default if TSO was enabled.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4324
	 * no longer assume, we must.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4325
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4326
	if (skb->protocol == htons(ETH_P_IP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
		tx_flags |= E1000_TX_FLAGS_IPV4;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
	/* if count is 0 then mapping error has occured */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
	count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
	if (count) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
		e1000_tx_queue(adapter, tx_flags, count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4333
		/* Make sure there is space in the ring for the next send. */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4334
		if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4335
			e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4336
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
		if (!adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
			dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
		tx_ring->buffer_info[first].time_stamp = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		tx_ring->next_to_use = first;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4342
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4343
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
	return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4346
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4347
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4348
 * e1000_tx_timeout - Respond to a Tx Hang
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4349
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4350
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4351
static void e1000_tx_timeout(struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4353
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4355
	/* Do the reset outside of interrupt context */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
	adapter->tx_timeout_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	schedule_work(&adapter->reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
static void e1000_reset_task(struct work_struct *work)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
	struct e1000_adapter *adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
	adapter = container_of(work, struct e1000_adapter, reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
	e1000e_reinit_locked(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
 * e1000_get_stats - Get System Network Statistics
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
 * Returns the address of the device statistics structure.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4373
 * The statistics are actually updated from the timer callback.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4376
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
	/* only return the current stats */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
	return &netdev->stats;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
 * e1000_change_mtu - Change the Maximum Transfer Unit
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
 * @new_mtu: new value for maximum frame size
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
 * Returns 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
		return -EBUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
	/* Jumbo frame support */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
	if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
		e_err("Jumbo Frames not supported.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
		return -EINVAL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4402
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4403
	/* Supported frame sizes */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
	    (max_frame > adapter->max_hw_frame_size)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
		e_err("Unsupported MTU setting\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4407
		return -EINVAL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
		msleep(1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	adapter->max_frame_size = max_frame;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
	netdev->mtu = new_mtu;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
		e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4419
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	 * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	 * means we reserve 2 more, this pushes us to allocate from the next
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	 * larger slab size.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	 * i.e. RXBUFFER_2048 --> size-4096 slab
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
	 * However with the new *_jumbo_rx* routines, jumbo receives will use
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	 * fragmented skbs
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4427
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
	if (max_frame <= 2048)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4429
		adapter->rx_buffer_len = 2048;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4430
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
		adapter->rx_buffer_len = 4096;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4432
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4433
	/* adjust allocation if LPE protects us, and we aren't using SBP */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	     (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4437
					 + ETH_FCS_LEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4438
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4439
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4440
		e1000e_up(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
		e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4444
	clear_bit(__E1000_RESETTING, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
			   int cmd)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4452
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	struct mii_ioctl_data *data = if_mii(ifr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	if (adapter->hw.phy.media_type != e1000_media_type_copper)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
		return -EOPNOTSUPP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	switch (cmd) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
	case SIOCGMIIPHY:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
		data->phy_id = adapter->hw.phy.addr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4461
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	case SIOCGMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
		e1000_phy_read_status(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4465
		switch (data->reg_num & 0x1F) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
		case MII_BMCR:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4467
			data->val_out = adapter->phy_regs.bmcr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4469
		case MII_BMSR:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
			data->val_out = adapter->phy_regs.bmsr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
		case MII_PHYSID1:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
			data->val_out = (adapter->hw.phy.id >> 16);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
		case MII_PHYSID2:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
			data->val_out = (adapter->hw.phy.id & 0xFFFF);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4477
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
		case MII_ADVERTISE:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4479
			data->val_out = adapter->phy_regs.advertise;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4481
		case MII_LPA:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
			data->val_out = adapter->phy_regs.lpa;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4484
		case MII_EXPANSION:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4485
			data->val_out = adapter->phy_regs.expansion;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4487
		case MII_CTRL1000:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
			data->val_out = adapter->phy_regs.ctrl1000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
		case MII_STAT1000:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
			data->val_out = adapter->phy_regs.stat1000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
		case MII_ESTATUS:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4494
			data->val_out = adapter->phy_regs.estatus;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4496
		default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
			return -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	case SIOCSMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
		return -EOPNOTSUPP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4503
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4504
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4506
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4508
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4509
	switch (cmd) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
	case SIOCGMIIPHY:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	case SIOCGMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
	case SIOCSMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		return e1000_mii_ioctl(netdev, ifr, cmd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
		return -EOPNOTSUPP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4518
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4519
static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
	u32 i, mac_reg;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
	u16 phy_reg;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4524
	int retval = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
	/* copy MAC RARs to PHY RARs */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
	for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		mac_reg = er32(RAL(i));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
		e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		mac_reg = er32(RAH(i));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
		e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4535
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
	/* copy MAC MTA to PHY MTA */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
	for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
		mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
		e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
		e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4541
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
	/* configure PHY Rx Control register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
	e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
	mac_reg = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
	if (mac_reg & E1000_RCTL_UPE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		phy_reg |= BM_RCTL_UPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
	if (mac_reg & E1000_RCTL_MPE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
		phy_reg |= BM_RCTL_MPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
	phy_reg &= ~(BM_RCTL_MO_MASK);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
	if (mac_reg & E1000_RCTL_MO_3)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
		phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4553
				<< BM_RCTL_MO_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
	if (mac_reg & E1000_RCTL_BAM)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
		phy_reg |= BM_RCTL_BAM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
	if (mac_reg & E1000_RCTL_PMCF)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
		phy_reg |= BM_RCTL_PMCF;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
	mac_reg = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
	if (mac_reg & E1000_CTRL_RFCE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		phy_reg |= BM_RCTL_RFCE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
	e1e_wphy(&adapter->hw, BM_RCTL, phy_reg);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
	/* enable PHY wakeup in MAC register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
	ew32(WUFC, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
	/* configure and enable PHY wakeup in PHY registers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	e1e_wphy(&adapter->hw, BM_WUFC, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
	e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
	/* activate PHY wakeup */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	retval = hw->phy.ops.acquire(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4573
	if (retval) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
		e_err("Could not acquire PHY\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
		return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4576
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4577
	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4578
	                         (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4579
	retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	if (retval) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
		e_err("Could not read PHY page 769\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4582
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4583
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
	retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	if (retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
		e_err("Could not set PHY Host Wakeup bit\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
out:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
	hw->phy.ops.release(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4590
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4591
	return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4592
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	u32 ctrl, ctrl_ext, rctl, status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
	u32 wufc = adapter->wol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
	int retval = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4603
	netif_device_detach(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4604
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4605
	if (netif_running(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4606
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->state));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
		e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
		e1000_free_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4610
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4611
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4612
	retval = pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	if (retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
		return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4616
	status = er32(STATUS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4617
	if (status & E1000_STATUS_LU)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
		wufc &= ~E1000_WUFC_LNKC;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4620
	if (wufc) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4621
		e1000_setup_rctl(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
		e1000_set_multi(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
		/* turn on all-multi mode if wake on multicast is enabled */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		if (wufc & E1000_WUFC_MC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4626
			rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
			rctl |= E1000_RCTL_MPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
			ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4629
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4630
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4631
		ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4632
		/* advertise wake from D3Cold */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
		#define E1000_CTRL_ADVD3WUC 0x00100000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
		/* phy power management enable */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
		#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
		ctrl |= E1000_CTRL_ADVD3WUC;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4638
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
		ew32(CTRL, ctrl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4640
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4641
		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4642
		    adapter->hw.phy.media_type ==
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4643
		    e1000_media_type_internal_serdes) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
			/* keep the laser running in D3 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4645
			ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
			ew32(CTRL_EXT, ctrl_ext);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4648
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4649
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
		if (adapter->flags & FLAG_IS_ICH)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4651
			e1000e_disable_gig_wol_ich8lan(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4653
		/* Allow time for pending master requests to run */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
		e1000e_disable_pcie_master(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4655
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4656
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
			/* enable wakeup by the PHY */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4658
			retval = e1000_init_phy_wakeup(adapter, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
			if (retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
				return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
			/* enable wakeup by the MAC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
			ew32(WUFC, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
			ew32(WUC, E1000_WUC_PME_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4665
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4666
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
		ew32(WUC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
		ew32(WUFC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4670
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	*enable_wake = !!wufc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4672
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	/* make sure adapter isn't asleep if manageability is enabled */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
	    (hw->mac.ops.check_mng_mode(hw)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
		*enable_wake = true;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
	if (adapter->hw.phy.type == e1000_phy_igp_3)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4680
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4681
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
	 * would have already happened in close and is redundant.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
	e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4686
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4687
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	if (sleep && wake) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
		pci_prepare_to_sleep(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4698
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4699
	pci_wake_from_d3(pdev, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	pci_set_power_state(pdev, PCI_D3hot);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4701
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4702
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4703
static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
                                    bool wake)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4705
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4706
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4707
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
	 * The pci-e switch on some quad port adapters will report a
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
	 * correctable error when the MAC transitions from D0 to D3.  To
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
	 * prevent this we need to mask off the correctable errors on the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
	 * downstream port of the pci-e switch.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		struct pci_dev *us_dev = pdev->bus->self;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
		int pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		u16 devctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
		pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
		                      (devctl & ~PCI_EXP_DEVCTL_CERE));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
		e1000_power_off(pdev, sleep, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
		pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		e1000_power_off(pdev, sleep, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4729
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4730
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4731
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
static void e1000e_disable_l1aspm(struct pci_dev *pdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
	int pos;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
	u16 val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4737
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4738
	 * 82573 workaround - disable L1 ASPM on mobile chipsets
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4739
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4740
	 * L1 ASPM on various mobile (ich7) chipsets do not behave properly
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	 * resulting in lost data or garbage information on the pci-e link
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4742
	 * level. This could result in (false) bad EEPROM checksum errors,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4743
	 * long ping times (up to 2s) or even a system freeze/hang.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4744
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4745
	 * Unfortunately this feature saves about 1W power consumption when
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
	 * active.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4747
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4748
	pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
	pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
	if (val & 0x2) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
		dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
		val &= ~0x2;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4753
		pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4755
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4756
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
#ifdef CONFIG_PM
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
	int retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
	bool wake;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4765
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4766
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
		return -EBUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4769
	retval = __e1000_shutdown(pdev, &wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	if (!retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
		e1000_complete_shutdown(pdev, true, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4774
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4775
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
static int e1000_resume(struct pci_dev *pdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4781
	u32 err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
		return -EBUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4785
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
	pci_set_power_state(pdev, PCI_D0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
	pci_restore_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4788
	pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
	e1000e_disable_l1aspm(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4791
	err = pci_enable_device_mem(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
	if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
		dev_err(&pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
			"Cannot enable PCI device from suspend\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
		return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4797
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4798
	pci_set_master(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	pci_enable_wake(pdev, PCI_D3hot, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
	pci_enable_wake(pdev, PCI_D3cold, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
	if (netif_running(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
		err = e1000_request_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
		if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
			return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4808
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4809
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4810
	e1000e_power_up_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4811
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4812
	/* report the system wakeup cause from S3/S4 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4814
		u16 phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4816
		e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
		if (phy_data) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
			e_info("PHY Wakeup cause - %s\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
				phy_data & E1000_WUS_EX ? "Unicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
				phy_data & E1000_WUS_MC ? "Multicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
				phy_data & E1000_WUS_BC ? "Broadcast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
				phy_data & E1000_WUS_MAG ? "Magic Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
				phy_data & E1000_WUS_LNKC ? "Link Status "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
				" Change" : "other");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4826
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4827
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4828
		u32 wus = er32(WUS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
		if (wus) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
			e_info("MAC Wakeup cause - %s\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
				wus & E1000_WUS_EX ? "Unicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
				wus & E1000_WUS_MC ? "Multicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
				wus & E1000_WUS_BC ? "Broadcast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
				wus & E1000_WUS_MAG ? "Magic Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
				wus & E1000_WUS_LNKC ? "Link Status Change" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
				"other");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
		ew32(WUS, ~0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4839
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4840
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
	e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
	e1000_init_manageability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4844
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4845
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
		e1000e_up(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4847
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
	netif_device_attach(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4850
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4851
	 * If the controller has AMT, do not set DRV_LOAD until the interface
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
	 * is up.  For all other cases, let the f/w know that the h/w is now
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
	 * under the control of the driver.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4854
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4856
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4857
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4858
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4859
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4860
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
static void e1000_shutdown(struct pci_dev *pdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4864
	bool wake = false;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	struct e1000_adapter *adapter = netdev_priv(netdev);
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  4867
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
	if (adapter->ecdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4870
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4871
	__e1000_shutdown(pdev, &wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4872
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4873
	if (system_state == SYSTEM_POWER_OFF)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
		e1000_complete_shutdown(pdev, false, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
#ifdef CONFIG_NET_POLL_CONTROLLER
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4878
/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4879
 * Polling 'interrupt' - used by things like netconsole to send skbs
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
 * without having to re-enable interrupts. It's not called while
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4881
 * the interrupt routine is executing.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
static void e1000_netpoll(struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
	disable_irq(adapter->pdev->irq);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4888
	e1000_intr(adapter->pdev->irq, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4890
	enable_irq(adapter->pdev->irq);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4894
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4895
 * e1000_io_error_detected - called when PCI error is detected
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
 * @pdev: Pointer to PCI device
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4897
 * @state: The current pci connection state
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4898
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
 * This function is called after a PCI bus error affecting
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
 * this device has been detected.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4901
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
						pci_channel_state_t state)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
	netif_device_detach(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4910
	if (state == pci_channel_io_perm_failure)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4911
		return PCI_ERS_RESULT_DISCONNECT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
		e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4917
	/* Request a slot slot reset. */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4918
	return PCI_ERS_RESULT_NEED_RESET;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4921
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4922
 * e1000_io_slot_reset - called after the pci bus has been reset.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
 * @pdev: Pointer to PCI device
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4925
 * Restart the card from scratch, as if from a cold-boot. Implementation
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
 * resembles the first-half of the e1000_resume routine.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
	pci_ers_result_t result;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4935
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4936
	e1000e_disable_l1aspm(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4937
	err = pci_enable_device_mem(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4938
	if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4939
		dev_err(&pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
			"Cannot re-enable PCI device after reset.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
		result = PCI_ERS_RESULT_DISCONNECT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
		pci_set_master(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
		pci_restore_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
		pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
		pci_enable_wake(pdev, PCI_D3hot, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
		pci_enable_wake(pdev, PCI_D3cold, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
		e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
		ew32(WUS, ~0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4952
		result = PCI_ERS_RESULT_RECOVERED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4953
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4954
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4955
	pci_cleanup_aer_uncorrect_error_status(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4956
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
	return result;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
 * e1000_io_resume - called when traffic can start flowing again.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4962
 * @pdev: Pointer to PCI device
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
 * This callback is called when the error recovery driver tells us that
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
 * its OK to resume normal operation. Implementation resembles the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
 * second-half of the e1000_resume routine.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
static void e1000_io_resume(struct pci_dev *pdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4969
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4970
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
	e1000_init_manageability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
	if (netif_running(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
		if (e1000e_up(adapter)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
			dev_err(&pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4978
				"can't bring device back up after reset\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
			return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4980
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
	netif_device_attach(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4984
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
	 * If the controller has AMT, do not set DRV_LOAD until the interface
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
	 * is up.  For all other cases, let the f/w know that the h/w is now
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
	 * under the control of the driver.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4992
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4993
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4994
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4995
static void e1000_print_device_info(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
	u32 pba_num;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5001
	/* print bus type/speed/width info */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
	e_info("(PCI Express:2.5GB/s:%s) %pM\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
	       /* bus width */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
	        "Width x1"),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
	       /* MAC address */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
	       netdev->dev_addr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
	e_info("Intel(R) PRO/%s Network Connection\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	e1000e_read_pba_num(hw, &pba_num);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
	e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	       hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5014
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5015
static void e1000_eeprom_checks(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5016
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5017
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
	int ret_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
	u16 buf = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
	if (hw->mac.type != e1000_82573)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
	if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
		/* Deep Smart Power Down (DSPD) */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
		dev_warn(&adapter->pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
			 "Warning: detected DSPD enabled in EEPROM\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5029
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5030
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
	ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
		/* ASPM enable */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
		dev_warn(&adapter->pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
			 "Warning: detected ASPM enabled in EEPROM\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5036
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5038
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5039
static const struct net_device_ops e1000e_netdev_ops = {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	.ndo_open		= e1000_open,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
	.ndo_stop		= e1000_close,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
	.ndo_start_xmit		= e1000_xmit_frame,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
	.ndo_get_stats		= e1000_get_stats,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5044
	.ndo_set_multicast_list	= e1000_set_multi,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
	.ndo_set_mac_address	= e1000_set_mac,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	.ndo_change_mtu		= e1000_change_mtu,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
	.ndo_do_ioctl		= e1000_ioctl,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	.ndo_tx_timeout		= e1000_tx_timeout,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
	.ndo_validate_addr	= eth_validate_addr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5053
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5054
#ifdef CONFIG_NET_POLL_CONTROLLER
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	.ndo_poll_controller	= e1000_netpoll,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5057
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5058
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5059
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5060
 * ec_poll - Ethercat poll Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
 * @netdev: net device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
 * This function can never fail.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
void ec_poll(struct net_device *netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5070
	if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5071
		e1000_watchdog((unsigned long) adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5072
		adapter->ec_watchdog_jiffies = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
#ifdef CONFIG_PCI_MSI
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
	e1000_intr_msi(0,netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
#else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	e1000_intr(0,netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5080
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5081
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5082
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
 * e1000_probe - Device Initialization Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5084
 * @pdev: PCI device information struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
 * @ent: entry in e1000_pci_tbl
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5087
 * Returns 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
 * e1000_probe initializes an adapter identified by a pci_dev structure.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5090
 * The OS initialization, configuring of the adapter private structure,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
 * and a hardware reset occur.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
static int __devinit e1000_probe(struct pci_dev *pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5094
				 const struct pci_device_id *ent)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
	struct net_device *netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
	struct e1000_adapter *adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
	struct e1000_hw *hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
	const struct e1000_info *ei = e1000_info_tbl[ent->driver_data];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
	resource_size_t mmio_start, mmio_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5101
	resource_size_t flash_start, flash_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5102
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5103
	static int cards_found;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	int i, err, pci_using_dac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
	u16 eeprom_data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
	e1000e_disable_l1aspm(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
	err = pci_enable_device_mem(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
		return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5113
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5114
	pci_using_dac = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5115
	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
	if (!err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
		if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5119
			pci_using_dac = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5120
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5122
		if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
			err = pci_set_consistent_dma_mask(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
							  DMA_BIT_MASK(32));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5125
			if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5126
				dev_err(&pdev->dev, "No usable DMA "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
					"configuration, aborting\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
				goto err_dma;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5129
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5132
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
	err = pci_request_selected_regions_exclusive(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
	                                  pci_select_bars(pdev, IORESOURCE_MEM),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	                                  e1000e_driver_name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
		goto err_pci_reg;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5138
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5139
	/* AER (Advanced Error Reporting) hooks */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5140
	pci_enable_pcie_error_reporting(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5142
	pci_set_master(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	/* PCI config space info */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5144
	err = pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5145
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
		goto err_alloc_etherdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5147
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5148
	err = -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
	if (!netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
		goto err_alloc_etherdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
	SET_NETDEV_DEV(netdev, &pdev->dev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
	pci_set_drvdata(pdev, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
	adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
	hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5158
	adapter->netdev = netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5159
	adapter->pdev = pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
	adapter->ei = ei;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5161
	adapter->pba = ei->pba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5162
	adapter->flags = ei->flags;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5163
	adapter->flags2 = ei->flags2;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5164
	adapter->hw.adapter = adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5165
	adapter->hw.mac.type = ei->mac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
	adapter->max_hw_frame_size = ei->max_hw_frame_size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5167
	adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	mmio_start = pci_resource_start(pdev, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5170
	mmio_len = pci_resource_len(pdev, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5171
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
	err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
	if (!adapter->hw.hw_addr)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
		goto err_ioremap;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5176
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5177
	if ((adapter->flags & FLAG_HAS_FLASH) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5179
		flash_start = pci_resource_start(pdev, 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5180
		flash_len = pci_resource_len(pdev, 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
		adapter->hw.flash_address = ioremap(flash_start, flash_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
		if (!adapter->hw.flash_address)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5183
			goto err_flashmap;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
	/* construct the net_device struct */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
	netdev->netdev_ops		= &e1000e_netdev_ops;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5188
	e1000e_set_ethtool_ops(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5189
	netdev->watchdog_timeo		= 5 * HZ;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5192
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
	netdev->mem_start = mmio_start;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
	netdev->mem_end = mmio_start + mmio_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5195
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
	adapter->bd_number = cards_found++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
	e1000e_check_options(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
	/* setup adapter struct */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	err = e1000_sw_init(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5203
		goto err_sw_init;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5204
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
	err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
	memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5210
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	err = ei->get_variants(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5212
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
		goto err_hw_init;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5215
	if ((adapter->flags & FLAG_IS_ICH) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	    (adapter->flags & FLAG_READ_ONLY_NVM))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5218
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5219
	hw->mac.ops.get_bus_info(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5221
	adapter->hw.phy.autoneg_wait_to_complete = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5222
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
	/* Copper options */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
		adapter->hw.phy.disable_polarity_correction = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
		adapter->hw.phy.ms_type = e1000_ms_hw_default;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
	if (e1000_check_reset_block(&adapter->hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
		e_info("PHY reset is blocked due to SOL/IDER session.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5233
	netdev->features = NETIF_F_SG |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
			   NETIF_F_HW_CSUM |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
			   NETIF_F_HW_VLAN_TX |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
			   NETIF_F_HW_VLAN_RX;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
		netdev->features |= NETIF_F_HW_VLAN_FILTER;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
	netdev->features |= NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
	netdev->features |= NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
	netdev->vlan_features |= NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
	netdev->vlan_features |= NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
	netdev->vlan_features |= NETIF_F_HW_CSUM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
	netdev->vlan_features |= NETIF_F_SG;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
	if (pci_using_dac)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
		netdev->features |= NETIF_F_HIGHDMA;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
	if (e1000e_enable_mng_pass_thru(&adapter->hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
		adapter->flags |= FLAG_MNG_PT_ENABLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
	 * before reading the NVM, reset the controller to
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
	 * put the device in a known good starting state
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
	adapter->hw.mac.ops.reset_hw(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	 * systems with ASPM and others may see the checksum fail on the first
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
	 * attempt. Let's give it a few tries
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5264
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5265
	for (i = 0;; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
		if (i == 2) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
			e_err("The NVM Checksum Is Not Valid\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
			err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5271
			goto err_eeprom;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5272
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5273
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5274
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5275
	e1000_eeprom_checks(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5276
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	/* copy the MAC address out of the NVM */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5278
	if (e1000e_read_mac_addr(&adapter->hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
		e_err("NVM Read Error while reading MAC address\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5280
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5281
	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5282
	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5283
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5284
	if (!is_valid_ether_addr(netdev->perm_addr)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
		e_err("Invalid MAC Address: %pM\n", netdev->perm_addr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
		err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
		goto err_eeprom;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	init_timer(&adapter->watchdog_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	adapter->watchdog_timer.function = &e1000_watchdog;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	adapter->watchdog_timer.data = (unsigned long) adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
	init_timer(&adapter->phy_info_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
	adapter->phy_info_timer.function = &e1000_update_phy_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
	adapter->phy_info_timer.data = (unsigned long) adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5297
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5298
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
	INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5302
	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5303
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
	/* Initialize link parameters. User can change them with ethtool */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
	adapter->hw.mac.autoneg = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
	adapter->fc_autoneg = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
	adapter->hw.fc.requested_mode = e1000_fc_default;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
	adapter->hw.fc.current_mode = e1000_fc_default;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
	adapter->hw.phy.autoneg_advertised = 0x2f;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
	/* ring size defaults */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
	adapter->rx_ring->count = 256;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
	adapter->tx_ring->count = 256;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5315
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5316
	 * Initial Wake on LAN setting - If APM wake is enabled in
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
	 * the EEPROM, enable the ACPI Magic Packet filter
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
	if (adapter->flags & FLAG_APME_IN_WUC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
		/* APME bit in EEPROM is mapped to WUC.APME */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
		eeprom_data = er32(WUC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
		eeprom_apme_mask = E1000_WUC_APME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
		if (eeprom_data & E1000_WUC_PHY_WAKE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
	} else if (adapter->flags & FLAG_APME_IN_CTRL3) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5326
		if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
		    (adapter->hw.bus.func == 1))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
			e1000_read_nvm(&adapter->hw,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
				NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
			e1000_read_nvm(&adapter->hw,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5332
				NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5333
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5334
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5335
	/* fetch WoL from EEPROM */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5336
	if (eeprom_data & eeprom_apme_mask)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5337
		adapter->eeprom_wol |= E1000_WUFC_MAG;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5338
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5339
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5340
	 * now that we have the eeprom settings, apply the special cases
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5341
	 * where the eeprom may be wrong or the board simply won't support
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	 * wake on lan on a particular port
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5343
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5344
	if (!(adapter->flags & FLAG_HAS_WOL))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5345
		adapter->eeprom_wol = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5346
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	/* initialize the wol settings based on the eeprom settings */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5348
	adapter->wol = adapter->eeprom_wol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5349
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5350
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
	/* save off EEPROM version number */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5352
	e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5353
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5354
	/* reset the hardware with the new settings */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
	e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5356
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5358
	 * If the controller has AMT, do not set DRV_LOAD until the interface
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	 * is up.  For all other cases, let the f/w know that the h/w is now
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5360
	 * under the control of the driver.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5362
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5365
	adapter->ecdev = ecdev_offer(netdev,ec_poll,THIS_MODULE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5366
	if (adapter->ecdev) {
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  5367
		err = ecdev_open(adapter->ecdev);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2174
diff changeset
  5368
		if (err) {
2174
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5369
			ecdev_withdraw(adapter->ecdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5370
			goto err_register;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5371
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5372
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
		strcpy(netdev->name, "eth%d");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5374
		err = register_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5375
		if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5376
			goto err_register;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5377
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5378
		/* carrier off reporting is important to ethtool even BEFORE open */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5379
		netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5380
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5381
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5382
	e1000_print_device_info(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5384
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5385
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5386
err_register:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5388
		e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5389
err_eeprom:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
	if (!e1000_check_reset_block(&adapter->hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5391
		e1000_phy_hw_reset(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5392
err_hw_init:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5393
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5394
	kfree(adapter->tx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
	kfree(adapter->rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
err_sw_init:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
	if (adapter->hw.flash_address)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
		iounmap(adapter->hw.flash_address);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
err_flashmap:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
	iounmap(adapter->hw.hw_addr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
err_ioremap:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
	free_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
err_alloc_etherdev:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
	pci_release_selected_regions(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
	                             pci_select_bars(pdev, IORESOURCE_MEM));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
err_pci_reg:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
err_dma:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5412
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5413
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5414
 * e1000_remove - Device Removal Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
 * @pdev: PCI device information struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5416
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5417
 * e1000_remove is called by the PCI subsystem to alert the driver
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5418
 * that it should release a PCI device.  The could be caused by a
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5419
 * Hot-Plug event, or because the driver is going to be removed from
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
 * memory.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5421
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5422
static void __devexit e1000_remove(struct pci_dev *pdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5424
	struct net_device *netdev = pci_get_drvdata(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5426
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
	 * flush_scheduled work may reschedule our watchdog task, so
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
	 * explicitly disable watchdog tasks from being rescheduled
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5430
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5431
	set_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
	del_timer_sync(&adapter->watchdog_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
	del_timer_sync(&adapter->phy_info_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
	cancel_work_sync(&adapter->reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
	cancel_work_sync(&adapter->watchdog_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5437
	cancel_work_sync(&adapter->downshift_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
	cancel_work_sync(&adapter->update_phy_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
	cancel_work_sync(&adapter->print_hang_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
	flush_scheduled_work();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
	if (!(netdev->flags & IFF_UP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
		e1000_power_down_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5444
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5445
	if (adapter->ecdev) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
		ecdev_close(adapter->ecdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5447
		ecdev_withdraw(adapter->ecdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
		unregister_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5450
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5451
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5452
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5453
	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5454
	 * would have already happened in close and is redundant.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5455
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5456
	e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5457
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5458
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5459
	kfree(adapter->tx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5460
	kfree(adapter->rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5461
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5462
	iounmap(adapter->hw.hw_addr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5463
	if (adapter->hw.flash_address)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5464
		iounmap(adapter->hw.flash_address);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5465
	pci_release_selected_regions(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5466
	                             pci_select_bars(pdev, IORESOURCE_MEM));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5467
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5468
	free_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5469
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5470
	/* AER disable */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5471
	pci_disable_pcie_error_reporting(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5472
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5473
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5474
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5475
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5476
/* PCI Error Recovery (ERS) */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5477
static struct pci_error_handlers e1000_err_handler = {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5478
	.error_detected = e1000_io_error_detected,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5479
	.slot_reset = e1000_io_slot_reset,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5480
	.resume = e1000_io_resume,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5481
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5482
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5483
static struct pci_device_id e1000_pci_tbl[] = {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5484
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5485
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5486
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5487
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5488
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5489
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5490
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5491
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5492
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5493
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5494
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5495
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5496
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5497
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5498
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5499
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5500
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5501
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5502
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5503
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5504
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82574LA), board_82574 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5505
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82583V), board_82583 },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5506
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5507
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5508
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5509
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5510
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5511
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5512
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5513
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5514
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5515
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5516
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5517
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5518
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5519
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5520
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5521
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5522
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5523
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_82567V_3), board_ich8lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5524
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5525
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5526
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5527
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5528
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5529
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5530
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5531
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5532
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5533
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5534
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5535
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5536
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5537
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5538
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5539
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5540
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5541
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5542
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5543
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5544
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5545
	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5546
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5547
	{ }	/* terminate list */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5548
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5549
//MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5550
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5551
/* PCI Device API Driver */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5552
static struct pci_driver e1000_driver = {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5553
	.name     = e1000e_driver_name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5554
	.id_table = e1000_pci_tbl,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5555
	.probe    = e1000_probe,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5556
	.remove   = __devexit_p(e1000_remove),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5557
#ifdef CONFIG_PM
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5558
	/* Power Management Hooks */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5559
	.suspend  = e1000_suspend,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5560
	.resume   = e1000_resume,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5561
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5562
	.shutdown = e1000_shutdown,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5563
	.err_handler = &e1000_err_handler
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5564
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5565
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5566
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5567
 * e1000_init_module - Driver Registration Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5568
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5569
 * e1000_init_module is the first routine called when the driver is
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5570
 * loaded. All it does is register with the PCI subsystem.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5571
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5572
static int __init e1000_init_module(void)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5573
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5574
	int ret;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5575
	printk(KERN_INFO "%s: Ethercat-capable Intel(R) PRO/1000 Network Driver - %s\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5576
	       e1000e_driver_name, e1000e_driver_version);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5577
	printk(KERN_INFO "%s: Copyright (c) 1999 - 2009 Intel Corporation.\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5578
	       e1000e_driver_name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5579
	ret = pci_register_driver(&e1000_driver);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5580
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5581
	return ret;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5582
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5583
module_init(e1000_init_module);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5584
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5585
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5586
 * e1000_exit_module - Driver Exit Cleanup Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5587
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5588
 * e1000_exit_module is called just before the driver is removed
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5589
 * from memory.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5590
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5591
static void __exit e1000_exit_module(void)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5592
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5593
	pci_unregister_driver(&e1000_driver);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5594
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5595
module_exit(e1000_exit_module);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5596
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5597
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5598
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5599
MODULE_DESCRIPTION("Ethercat-capable Intel(R) PRO/1000 Network Driver");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5600
MODULE_LICENSE("GPL");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5601
MODULE_VERSION(DRV_VERSION);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5602
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5603
/* e1000_main.c */