devices/e1000e/netdev-2.6.33-orig.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 10:12:55 -0400
changeset 2625 e25af8bd3957
parent 2174 cedacf485d81
permissions -rw-r--r--
Eoe mac address now derived from unique mac.
The EoE MAC address is now derived from the NIC part of the first global
unique MAC address of the linked list of available network interfaces or
otherwise the MAC address used by the EtherCAT master. The EoE MAC address
will get the format 02:NIC:NIC:NIC:RP:RP where NIC comes from the unique MAC
address (if available) and RP is the ring position of the EoE slave.
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
*******************************************************************************/
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
#include <linux/module.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
#include <linux/types.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/init.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/pci.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/vmalloc.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/pagemap.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/delay.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/netdevice.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/tcp.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/ipv6.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
#include <net/checksum.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include <net/ip6_checksum.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
#include <linux/mii.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
#include <linux/ethtool.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
#include <linux/if_vlan.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
#include <linux/cpu.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
#include <linux/smp.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
#include <linux/pm_qos_params.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
#include <linux/aer.h>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
#include "e1000.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
#define DRV_VERSION "1.0.2-k2"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
char e1000e_driver_name[] = "e1000e";
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
const char e1000e_driver_version[] = DRV_VERSION;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
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
    56
	[board_82571]		= &e1000_82571_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
	[board_82572]		= &e1000_82572_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
	[board_82573]		= &e1000_82573_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
	[board_82574]		= &e1000_82574_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
	[board_82583]		= &e1000_82583_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
	[board_80003es2lan]	= &e1000_es2_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
	[board_ich8lan]		= &e1000_ich8_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	[board_ich9lan]		= &e1000_ich9_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	[board_ich10lan]	= &e1000_ich10_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	[board_pchlan]		= &e1000_pch_info,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
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
 * 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
    70
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
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
    72
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	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
    74
		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
    75
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	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
    77
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
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
 * 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
    81
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
 * @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
    83
 * @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
    84
 * @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
    85
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
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
    87
			      struct net_device *netdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
			      struct sk_buff *skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
			      u8 status, __le16 vlan)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	skb->protocol = eth_type_trans(skb, netdev);
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
	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
    94
		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
				 le16_to_cpu(vlan), skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
		napi_gro_receive(&adapter->napi, skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
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
 * 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
   102
 * @adapter:     board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
 * @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
   104
 * @csum:	receive descriptor csum field
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
 * @sk_buff:     socket buffer with received data
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
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
   108
			      u32 csum, struct sk_buff *skb)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	u16 status = (u16)status_err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	u8 errors = (u8)(status_err >> 24);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	skb->ip_summed = CHECKSUM_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
	/* Ignore Checksum bit is set */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
	if (status & E1000_RXD_STAT_IXSM)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	/* TCP/UDP checksum error bit is set */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	if (errors & E1000_RXD_ERR_TCPE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
		/* let the stack verify checksum errors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
		adapter->hw_csum_err++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
	/* TCP/UDP Checksum has not been calculated */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
	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
   126
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
	/* 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
   129
	if (status & E1000_RXD_STAT_TCPCS) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
		/* TCP checksum is good */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
		skb->ip_summed = CHECKSUM_UNNECESSARY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
		 * IP fragment with UDP payload
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
		 * 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
   136
		 * 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
   137
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
		__sum16 sum = (__force __sum16)htons(csum);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
		skb->csum = csum_unfold(~sum);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
		skb->ip_summed = CHECKSUM_COMPLETE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	adapter->hw_csum_good++;
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
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
 * 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
   147
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
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
   150
				   int cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
	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
   155
	struct e1000_rx_desc *rx_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
	unsigned int bufsz = adapter->rx_buffer_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	i = rx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
	while (cleaned_count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
		if (skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
			skb_trim(skb, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
			goto map_skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		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
   172
		if (!skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
			/* Better luck next round */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
			adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
		buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
map_skb:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
		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
   181
						  adapter->rx_buffer_len,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
						  PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
		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
   184
			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
   185
			adapter->rx_dma_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		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
   190
		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
   191
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	if (rx_ring->next_to_use != i) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
		rx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		if (i-- == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
			i = (rx_ring->count - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
		 * 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
   205
		 * 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
   206
		 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
		 * such as IA-64).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
		wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
		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
   211
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
}
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
 * 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
   216
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
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
   219
				      int cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
	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
   224
	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
   225
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	struct e1000_ps_page *ps_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	unsigned int i, j;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	i = rx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	while (cleaned_count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
		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
   235
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
		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
   237
			ps_page = &buffer_info->ps_pages[j];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
			if (j >= adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
				/* 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
   240
				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
   241
				continue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
			if (!ps_page->page) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
				ps_page->page = alloc_page(GFP_ATOMIC);
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
					adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
					goto no_buffers;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
				ps_page->dma = pci_map_page(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
						   ps_page->page,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
						   0, PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
						   PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
				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
   254
					dev_err(&adapter->pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
					  "RX DMA page map failed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
					adapter->rx_dma_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
					goto no_buffers;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
			}
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
			 * Refresh the desc even if buffer_addrs
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
			 * didn't change because each write-back
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
			 * erases this info.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
			rx_desc->read.buffer_addr[j+1] =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
			     cpu_to_le64(ps_page->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
		skb = netdev_alloc_skb_ip_align(netdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
						adapter->rx_ps_bsize0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
		if (!skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
			adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		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
   279
						  adapter->rx_ps_bsize0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
						  PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
		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
   282
			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
   283
			adapter->rx_dma_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
			/* cleanup skb */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
			dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
			buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
		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
   291
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
no_buffers:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	if (rx_ring->next_to_use != i) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
		rx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
		if (!(i--))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
			i = (rx_ring->count - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		 * 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
   307
		 * 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
   308
		 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
		 * such as IA-64).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
		wmb();
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
		 * 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
   314
		 * 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
   315
		 * twice as much.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
		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
   318
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
}
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
 * 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
   323
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
 * @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
   325
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
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
   328
                                         int cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
	struct e1000_rx_desc *rx_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	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
   334
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	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
   338
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	i = rx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	while (cleaned_count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		if (skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
			skb_trim(skb, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
			goto check_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		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
   350
		if (unlikely(!skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
			/* Better luck next round */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
			adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
		buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
check_page:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
		/* allocate a new page if necessary */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
		if (!buffer_info->page) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
			buffer_info->page = alloc_page(GFP_ATOMIC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
			if (unlikely(!buffer_info->page)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
				adapter->alloc_rx_buff_failed++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
		}
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
		if (!buffer_info->dma)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
			buffer_info->dma = pci_map_page(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
			                                buffer_info->page, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
			                                PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
			                                PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
		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
   374
		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
   375
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		if (unlikely(++i == rx_ring->count))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	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
   382
		rx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
		if (unlikely(i-- == 0))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			i = (rx_ring->count - 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
		/* 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
   387
		 * 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
   388
		 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
		 * such as IA-64). */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
		wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		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
   392
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
}
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
 * 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
   397
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
 * 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
   400
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
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
   403
			       int *work_done, int work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
	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
   409
	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
   410
	struct e1000_buffer *buffer_info, *next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
	u32 length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	int cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	bool cleaned = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
	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
   416
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	i = rx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	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
   419
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	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
   422
		struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
		u8 status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
		if (*work_done >= work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
		(*work_done)++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
		status = rx_desc->status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
		buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
		prefetch(skb->data - NET_IP_ALIGN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
		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
   439
		prefetch(next_rxd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
		next_buffer = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
		cleaned = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
		cleaned_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
		pci_unmap_single(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
				 buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
				 adapter->rx_buffer_len,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
				 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
		buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
		length = le16_to_cpu(rx_desc->length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
		 * !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
   455
		 * 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
   456
		 * 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
   457
		 * 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
   458
		 * definition only a frame fragment
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
		if (unlikely(!(status & E1000_RXD_STAT_EOP)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
			adapter->flags2 |= FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
			/* 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
   465
			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
   466
			/* recycle */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
			buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
			if (status & E1000_RXD_STAT_EOP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		if (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
   474
			/* recycle */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
			buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		/* adjust length to remove Ethernet CRC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
			length -= 4;
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
		total_rx_bytes += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
		total_rx_packets++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
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
		 * code added for copybreak, this should improve
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
		 * performance for small packets with large amounts
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
		 * of reassembly being done in the stack
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
		if (length < copybreak) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
			struct sk_buff *new_skb =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
			    netdev_alloc_skb_ip_align(netdev, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
			if (new_skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
				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
   496
							       -NET_IP_ALIGN,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
							       (skb->data -
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
								NET_IP_ALIGN),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
							       (length +
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
				/* 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
   502
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
				skb = new_skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
			/* else just continue with the old one */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
		/* end copybreak code */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
		skb_put(skb, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
		/* Receive Checksum Offload */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		e1000_rx_checksum(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
				  (u32)(status) |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
				  ((u32)(rx_desc->errors) << 24),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
				  le16_to_cpu(rx_desc->csum), skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
		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
   517
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
next_desc:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
		rx_desc->status = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		/* 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
   522
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
			adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
			cleaned_count = 0;
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
		/* use prefetched values */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
		rx_desc = next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		buffer_info = next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
	rx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
	cleaned_count = e1000_desc_unused(rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
	if (cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
		adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
	adapter->total_rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	adapter->total_rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
	netdev->stats.rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	netdev->stats.rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
	return cleaned;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
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
   545
			     struct e1000_buffer *buffer_info)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	if (buffer_info->dma) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
		if (buffer_info->mapped_as_page)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
			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
   550
				       buffer_info->length, PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
			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
   553
					 buffer_info->length,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
					 PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
		buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	if (buffer_info->skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
		dev_kfree_skb_any(buffer_info->skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
		buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	buffer_info->time_stamp = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
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
   565
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	                                             struct e1000_adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
	                                             print_hang_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	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
   570
	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
   571
	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
   572
	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
   573
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
	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
   575
	u16 pci_status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
	e1e_rphy(hw, PHY_STATUS, &phy_status);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
	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
   579
	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
   580
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	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
   582
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	/* detected Hardware unit hang */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	e_err("Detected Hardware Unit Hang:\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
	      "  TDH                  <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
	      "  TDT                  <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	      "  next_to_use          <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
	      "  next_to_clean        <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	      "buffer_info[next_to_clean]:\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
	      "  time_stamp           <%lx>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	      "  next_to_watch        <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
	      "  jiffies              <%lx>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	      "  next_to_watch.status <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
	      "MAC Status             <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
	      "PHY Status             <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	      "PHY 1000BASE-T Status  <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	      "PHY Extended Status    <%x>\n"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
	      "PCI Status             <%x>\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
	      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
   600
	      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
   601
	      tx_ring->next_to_use,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
	      tx_ring->next_to_clean,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	      tx_ring->buffer_info[eop].time_stamp,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
	      eop,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
	      jiffies,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	      eop_desc->upper.fields.status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	      er32(STATUS),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
	      phy_status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
	      phy_1000t_status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	      phy_ext_status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
	      pci_status);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
 * 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
   616
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
 * 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
   619
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
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
   622
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	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
   626
	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
   627
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
	unsigned int i, eop;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
	unsigned int count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
	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
   631
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	i = tx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	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
   634
	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
   635
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	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
   637
	       (count < tx_ring->count)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
		bool cleaned = false;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
		for (; !cleaned; count++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
			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
   641
			buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
			cleaned = (i == eop);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
			if (cleaned) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
				struct sk_buff *skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
				unsigned int segs, bytecount;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
				segs = skb_shinfo(skb)->gso_segs ?: 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
				/* multiply data chunks by size of headers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
				bytecount = ((segs - 1) * skb_headlen(skb)) +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
					    skb->len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
				total_tx_packets += segs;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
				total_tx_bytes += bytecount;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
			e1000_put_txbuf(adapter, buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
			tx_desc->upper.data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
			i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
			if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
				i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
		}
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
		if (i == tx_ring->next_to_use)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
		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
   666
		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
   667
	}
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
	tx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
#define TX_WAKE_THRESHOLD 32
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
	if (count && netif_carrier_ok(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	    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
   674
		/* 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
   675
		 * sees the new next_to_clean.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
		smp_mb();
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
		if (netif_queue_stopped(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
		    !(test_bit(__E1000_DOWN, &adapter->state))) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
			netif_wake_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
			++adapter->restart_queue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
	if (adapter->detect_tx_hung) {
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
		 * 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
   689
		 * 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
   690
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
		adapter->detect_tx_hung = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
		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
   693
		    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
   694
			       + (adapter->tx_timeout_factor * HZ)) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
		    !(er32(STATUS) & E1000_STATUS_TXOFF)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
			schedule_work(&adapter->print_hang_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
			netif_stop_queue(netdev);
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
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
	adapter->total_tx_bytes += total_tx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
	adapter->total_tx_packets += total_tx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
	netdev->stats.tx_bytes += total_tx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	netdev->stats.tx_packets += total_tx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
	return (count < tx_ring->count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
 * 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
   709
 * @adapter: board private structure
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
 * 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
   712
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
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
   715
				  int *work_done, int work_to_do)
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
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	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
   719
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	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
   722
	struct e1000_buffer *buffer_info, *next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	struct e1000_ps_page *ps_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	unsigned int i, j;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
	u32 length, staterr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	int cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
	bool cleaned = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	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
   730
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	i = rx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	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
   733
	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
   734
	buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
	while (staterr & E1000_RXD_STAT_DD) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
		if (*work_done >= work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		(*work_done)++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
		skb = buffer_info->skb;
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
		/* 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
   743
		prefetch(skb->data - NET_IP_ALIGN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
		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
   749
		prefetch(next_rxd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
		next_buffer = &rx_ring->buffer_info[i];
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
		cleaned = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
		cleaned_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
		pci_unmap_single(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
				 adapter->rx_ps_bsize0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
				 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
		/* see !EOP comment in other rx routine */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
		if (!(staterr & E1000_RXD_STAT_EOP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
			adapter->flags2 |= FLAG2_IS_DISCARDING;
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
		if (adapter->flags2 & FLAG2_IS_DISCARDING) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
			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
   766
			      "packet\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
			dev_kfree_skb_irq(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
			if (staterr & E1000_RXD_STAT_EOP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
				adapter->flags2 &= ~FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		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
   774
			dev_kfree_skb_irq(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		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
   779
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		if (!length) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
			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
   782
			      "descriptors\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
			dev_kfree_skb_irq(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
			goto next_desc;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		/* Good Receive */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		skb_put(skb, length);
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
		{
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
		 * 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
   793
		 * more efficient than reusing j
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
		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
   796
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
		 * 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
   799
		 * 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
   800
		 * 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
   801
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
		if (l1 && (l1 <= copybreak) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
		    ((length + l1) <= adapter->rx_ps_bsize0)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
			u8 *vaddr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
			ps_page = &buffer_info->ps_pages[0];
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
			 * 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
   810
			 * 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
   811
			 * very long
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
			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
   814
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
			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
   816
			memcpy(skb_tail_pointer(skb), vaddr, l1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
			kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
			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
   819
				PAGE_SIZE, PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
			/* remove the CRC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
			if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
				l1 -= 4;
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
			skb_put(skb, l1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
			goto copydone;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		} /* if */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		}
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
		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
   831
			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
   832
			if (!length)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			ps_page = &buffer_info->ps_pages[j];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
			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
   837
				       PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
			ps_page->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
			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
   840
			ps_page->page = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
			skb->len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
			skb->data_len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
			skb->truesize += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
		}
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
		/* 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
   847
		 * 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
   848
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
		if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
			pskb_trim(skb, skb->len - 4);
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
copydone:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
		total_rx_bytes += skb->len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
		total_rx_packets++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
		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
   857
			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
   858
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
		if (rx_desc->wb.upper.header_status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
			   cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
			adapter->rx_hdr_split++;
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
		e1000_receive_skb(adapter, netdev, skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
				  staterr, rx_desc->wb.middle.vlan);
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
next_desc:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
		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
   868
		buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		/* 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
   871
		if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
			adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
			cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
		}
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
		/* use prefetched values */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
		rx_desc = next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
		buffer_info = next_buffer;
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
		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
   881
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	rx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	cleaned_count = e1000_desc_unused(rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	if (cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
		adapter->alloc_rx_buf(adapter, cleaned_count);
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
	adapter->total_rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	adapter->total_rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	netdev->stats.rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	netdev->stats.rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	return cleaned;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
 * e1000_consume_page - helper function
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
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
   899
                               u16 length)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	bi->page = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	skb->len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
	skb->data_len += length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	skb->truesize += length;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
 * 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
   909
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
 * 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
   912
 * is no guarantee that everything was cleaned
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
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
   916
                                     int *work_done, int work_to_do)
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
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
	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
   921
	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
   922
	struct e1000_buffer *buffer_info, *next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
	u32 length;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	int cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
	bool cleaned = false;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	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
   928
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	i = rx_ring->next_to_clean;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	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
   931
	buffer_info = &rx_ring->buffer_info[i];
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
	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
   934
		struct sk_buff *skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		u8 status;
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
		if (*work_done >= work_to_do)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		(*work_done)++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
		status = rx_desc->status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		skb = buffer_info->skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
		buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
		++i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
		if (i == rx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
			i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
		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
   949
		prefetch(next_rxd);
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
		next_buffer = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
		cleaned = true;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
		cleaned_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
		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
   956
		               PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
		buffer_info->dma = 0;
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
		length = le16_to_cpu(rx_desc->length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
		/* 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
   962
		if (unlikely((status & E1000_RXD_STAT_EOP) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
		    (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
   964
				/* recycle both page and skb */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
				/* 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
   967
				 * too */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
				if (rx_ring->rx_skb_top)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
					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
   970
				rx_ring->rx_skb_top = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
				goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
#define rxtop rx_ring->rx_skb_top
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
		if (!(status & E1000_RXD_STAT_EOP)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
			/* 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
   977
			if (!rxtop) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
				/* this is the beginning of a chain */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
				rxtop = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
				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
   981
				                   0, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
			} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
				/* this is the middle of a chain */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
				skb_fill_page_desc(rxtop,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
				    skb_shinfo(rxtop)->nr_frags,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
				    buffer_info->page, 0, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
				/* 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
   988
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
			e1000_consume_page(buffer_info, rxtop, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
			if (rxtop) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
				/* end of the chain */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
				skb_fill_page_desc(rxtop,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
				    skb_shinfo(rxtop)->nr_frags,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
				    buffer_info->page, 0, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
				/* 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
   999
				 * page */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
				buffer_info->skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
				skb = rxtop;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
				rxtop = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
				e1000_consume_page(buffer_info, skb, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
			} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
				/* 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
  1006
				 * 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
  1007
				if (length <= copybreak &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
				    skb_tailroom(skb) >= length) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
					u8 *vaddr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
					vaddr = kmap_atomic(buffer_info->page,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
					                   KM_SKB_DATA_SOFTIRQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
					memcpy(skb_tail_pointer(skb), vaddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
					       length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
					kunmap_atomic(vaddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
					              KM_SKB_DATA_SOFTIRQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
					/* 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
  1017
					 * buffer_info->page */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
					skb_put(skb, length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
				} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
					skb_fill_page_desc(skb, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
					                   buffer_info->page, 0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
				                           length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
					e1000_consume_page(buffer_info, skb,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
					                   length);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
		/* 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
  1030
		e1000_rx_checksum(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
		                  (u32)(status) |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
		                  ((u32)(rx_desc->errors) << 24),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		                  le16_to_cpu(rx_desc->csum), skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
		/* 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
  1036
		total_rx_bytes += skb->len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		total_rx_packets++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
		/* 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
  1040
		if (!pskb_may_pull(skb, ETH_HLEN)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
			e_err("pskb_may_pull failed.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
			dev_kfree_skb(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
			goto next_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
		e1000_receive_skb(adapter, netdev, skb, status,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
		                  rx_desc->special);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
next_desc:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
		rx_desc->status = 0;
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
		/* 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
  1053
		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
  1054
			adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
			cleaned_count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
		/* use prefetched values */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		rx_desc = next_rxd;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		buffer_info = next_buffer;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
	rx_ring->next_to_clean = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
	cleaned_count = e1000_desc_unused(rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
	if (cleaned_count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		adapter->alloc_rx_buf(adapter, cleaned_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
	adapter->total_rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
	adapter->total_rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
	netdev->stats.rx_bytes += total_rx_bytes;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
	netdev->stats.rx_packets += total_rx_packets;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
	return cleaned;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
 * 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
  1077
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
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
  1080
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
	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
  1082
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
	struct e1000_ps_page *ps_page;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
	unsigned int i, j;
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
	/* Free all the Rx ring sk_buffs */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
	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
  1089
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		if (buffer_info->dma) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
			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
  1092
				pci_unmap_single(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
						 adapter->rx_buffer_len,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
						 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
			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
  1096
				pci_unmap_page(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
				               PAGE_SIZE,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
				               PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
			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
  1100
				pci_unmap_single(pdev, buffer_info->dma,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
						 adapter->rx_ps_bsize0,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
						 PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
			buffer_info->dma = 0;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		if (buffer_info->page) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
			put_page(buffer_info->page);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
			buffer_info->page = NULL;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		if (buffer_info->skb) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
			dev_kfree_skb(buffer_info->skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
			buffer_info->skb = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		}
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
		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
  1117
			ps_page = &buffer_info->ps_pages[j];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			if (!ps_page->page)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			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
  1121
				       PCI_DMA_FROMDEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			ps_page->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
			put_page(ps_page->page);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
			ps_page->page = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
	/* 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
  1129
	if (rx_ring->rx_skb_top) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		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
  1131
		rx_ring->rx_skb_top = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	}
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
	/* Zero out the descriptor ring */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
	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
  1136
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
	rx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
	rx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
	adapter->flags2 &= ~FLAG2_IS_DISCARDING;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
	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
  1142
	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
  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
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
  1146
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
					struct e1000_adapter, downshift_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	e1000e_gig_downshift_workaround_ich8lan(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
 * e1000_intr_msi - Interrupt Handler
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
 * @irq: interrupt number
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
 * @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
  1157
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
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
  1159
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
	u32 icr = er32(ICR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
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
	 * read ICR disables interrupts using IAM
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	if (icr & E1000_ICR_LSC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		hw->mac.get_link_status = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
		 * 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
  1173
		 * disconnect (LSC) before accessing any PHY registers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		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
  1176
		    (!(er32(STATUS) & E1000_STATUS_LU)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
			schedule_work(&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
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		 * 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
  1181
		 * 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
  1182
		 * adapter in watchdog
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
		if (netif_carrier_ok(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
			/* disable receives */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
			u32 rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
			adapter->flags |= FLAG_RX_RESTART_NOW;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
		/* 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
  1192
		if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	if (napi_schedule_prep(&adapter->napi)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		adapter->total_tx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		adapter->total_tx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
		adapter->total_rx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		adapter->total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
		__napi_schedule(&adapter->napi);
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
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
}
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
 * e1000_intr - Interrupt Handler
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
 * @irq: interrupt number
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
 * @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
  1211
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
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
  1213
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
	u32 rctl, icr = er32(ICR);
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 (!icr || test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		return IRQ_NONE;  /* Not our interrupt */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
	 * 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
  1224
	 * 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
  1225
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
	if (!(icr & E1000_ICR_INT_ASSERTED))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		return IRQ_NONE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
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
	 * Interrupt Auto-Mask...upon reading ICR,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	 * interrupts are masked.  No need for the
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
	 * IMC write
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	if (icr & E1000_ICR_LSC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		hw->mac.get_link_status = 1;
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
		 * 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
  1239
		 * disconnect (LSC) before accessing any PHY registers
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
		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
  1242
		    (!(er32(STATUS) & E1000_STATUS_LU)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
			schedule_work(&adapter->downshift_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
		 * 80003ES2LAN workaround--
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
		 * 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
  1248
		 * disable receives here in the ISR and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		 * reset adapter in watchdog
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
		if (netif_carrier_ok(netdev) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
		    (adapter->flags & FLAG_RX_NEEDS_RESTART)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
			/* disable receives */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
			rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
			adapter->flags |= FLAG_RX_RESTART_NOW;
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
		/* 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
  1259
		if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	if (napi_schedule_prep(&adapter->napi)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
		adapter->total_tx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
		adapter->total_tx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		adapter->total_rx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		adapter->total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
		__napi_schedule(&adapter->napi);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
	return IRQ_HANDLED;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
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
  1275
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
	u32 icr = er32(ICR);
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
	if (!(icr & E1000_ICR_INT_ASSERTED)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
		if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
			ew32(IMS, E1000_IMS_OTHER);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		return IRQ_NONE;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
	if (icr & adapter->eiac_mask)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		ew32(ICS, (icr & adapter->eiac_mask));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
	if (icr & E1000_ICR_OTHER) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
		if (!(icr & E1000_ICR_LSC))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
			goto no_link_interrupt;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
		hw->mac.get_link_status = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
		/* 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
  1295
		if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
no_link_interrupt:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		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
  1302
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
	return IRQ_HANDLED;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
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
  1308
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	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
  1313
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
	adapter->total_tx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	adapter->total_tx_packets = 0;
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
	if (!e1000_clean_tx_irq(adapter))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
		/* 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
  1320
		ew32(ICS, tx_ring->ims_val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
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
  1326
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	/* 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
  1331
	 * previous interrupt.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
	if (adapter->rx_ring->set_itr) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		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
  1335
		       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
  1336
		adapter->rx_ring->set_itr = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	if (napi_schedule_prep(&adapter->napi)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		adapter->total_rx_bytes = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
		adapter->total_rx_packets = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		__napi_schedule(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
}
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
 * e1000_configure_msix - Configure MSI-X hardware
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
 * 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
  1351
 * generate MSI-X interrupts.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
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
  1354
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
	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
  1357
	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
  1358
	int vector = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
	u32 ctrl_ext, ivar = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	adapter->eiac_mask = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
	/* 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
  1364
	if (hw->mac.type == e1000_82574) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		u32 rfctl = er32(RFCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		rfctl |= E1000_RFCTL_ACK_DIS;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
		ew32(RFCTL, rfctl);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
#define E1000_IVAR_INT_ALLOC_VALID	0x8
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
	/* Configure Rx vector */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
	rx_ring->ims_val = E1000_IMS_RXQ0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
	adapter->eiac_mask |= rx_ring->ims_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	if (rx_ring->itr_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
		writel(1000000000 / (rx_ring->itr_val * 256),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
		       hw->hw_addr + rx_ring->itr_register);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
		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
  1379
	ivar = E1000_IVAR_INT_ALLOC_VALID | vector;
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
	/* Configure Tx vector */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
	tx_ring->ims_val = E1000_IMS_TXQ0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
	if (tx_ring->itr_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		writel(1000000000 / (tx_ring->itr_val * 256),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
		       hw->hw_addr + tx_ring->itr_register);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		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
  1389
	adapter->eiac_mask |= tx_ring->ims_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
	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
  1391
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	/* 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
  1393
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	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
  1395
	if (rx_ring->itr_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		writel(1000000000 / (rx_ring->itr_val * 256),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		       hw->hw_addr + E1000_EITR_82574(vector));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		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
  1400
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	/* Cause Tx interrupts on every write back */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
	ivar |= (1 << 31);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	ew32(IVAR, ivar);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	/* enable MSI-X PBA support */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
	ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
	ctrl_ext |= E1000_CTRL_EXT_PBA_CLR;
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
	/* Auto-Mask Other interrupts upon ICR read */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
#define E1000_EIAC_MASK_82574   0x01F00000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
	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
  1413
	ctrl_ext |= E1000_CTRL_EXT_EIAME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	ew32(CTRL_EXT, ctrl_ext);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	e1e_flush();
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
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
  1419
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		pci_disable_msix(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
		kfree(adapter->msix_entries);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
		adapter->msix_entries = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	} else if (adapter->flags & FLAG_MSI_ENABLED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
		pci_disable_msi(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
		adapter->flags &= ~FLAG_MSI_ENABLED;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
	return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
 * 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
  1434
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
 * 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
  1436
 * capabilities of the hardware and kernel.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
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
  1439
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	int numvecs, i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	switch (adapter->int_mode) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
	case E1000E_INT_MODE_MSIX:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
		if (adapter->flags & FLAG_HAS_MSIX) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
			numvecs = 3; /* RxQ0, TxQ0 and other */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
			adapter->msix_entries = kcalloc(numvecs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
						      sizeof(struct msix_entry),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
						      GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
			if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
				for (i = 0; i < numvecs; i++)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
					adapter->msix_entries[i].entry = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
				err = pci_enable_msix(adapter->pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
						      adapter->msix_entries,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
						      numvecs);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
				if (err == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
					return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
			/* 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
  1462
			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
  1463
			      "Falling back to MSI interrupts.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
			e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
		adapter->int_mode = E1000E_INT_MODE_MSI;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
		/* Fall through */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	case E1000E_INT_MODE_MSI:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
		if (!pci_enable_msi(adapter->pdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
			adapter->flags |= FLAG_MSI_ENABLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
			adapter->int_mode = E1000E_INT_MODE_LEGACY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
			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
  1474
			      "back to legacy interrupts.\n");
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
		/* Fall through */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	case E1000E_INT_MODE_LEGACY:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
		/* 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
  1479
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	}
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
	return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
}
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
 * e1000_request_msix - Initialize MSI-X interrupts
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
 * 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
  1489
 * kernel.
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
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
  1492
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	int err = 0, vector = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		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
  1498
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
		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
  1500
	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
  1501
			  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
  1502
			  netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
	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
  1506
	adapter->rx_ring->itr_val = adapter->itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	if (strlen(netdev->name) < (IFNAMSIZ - 5))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
		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
  1511
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		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
  1513
	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
  1514
			  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
  1515
			  netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	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
  1519
	adapter->tx_ring->itr_val = adapter->itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
	vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
	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
  1523
			  e1000_msix_other, 0, netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
	e1000_configure_msix(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
out:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
	return err;
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
 * e1000_request_irq - initialize interrupts
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
 * 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
  1537
 * capabilities of the hardware and kernel.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
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
  1540
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
		err = e1000_request_msix(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
		if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
			return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
		/* fall back to MSI */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
		e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
		adapter->int_mode = E1000E_INT_MODE_MSI;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
		e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	if (adapter->flags & FLAG_MSI_ENABLED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
		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
  1555
				  netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
			return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		/* fall back to legacy interrupt */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
	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
  1565
			  netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		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
  1568
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
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
  1573
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
		int vector = 0;
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
		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
  1580
		vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
		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
  1583
		vector++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
		/* Other Causes interrupt vector */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
		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
  1587
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	free_irq(adapter->pdev->irq, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
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
 * 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
  1595
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
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
  1597
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
	ew32(IMC, ~0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
	if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
		ew32(EIAC_82574, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
	synchronize_irq(adapter->pdev->irq);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
 * 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
  1609
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
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
  1611
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	struct e1000_hw *hw = &adapter->hw;
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
	if (adapter->msix_entries) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
		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
  1616
		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
  1617
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
		ew32(IMS, IMS_ENABLE_MASK);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	e1e_flush();
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
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
 * 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
  1625
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
 * 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
  1628
 * 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
  1629
 * 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
  1630
 * 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
  1631
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
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
  1633
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
	u32 ctrl_ext;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
	u32 swsm;
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
	/* 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
  1639
	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
  1640
		swsm = er32(SWSM);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	} 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
  1643
		ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		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
  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
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
 * 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
  1650
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
 * 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
  1653
 * 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
  1654
 * 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
  1655
 * 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
  1656
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
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
  1659
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
	u32 ctrl_ext;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
	u32 swsm;
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
	/* 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
  1665
	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
  1666
		swsm = er32(SWSM);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
	} 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
  1669
		ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
		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
  1671
	}
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
 * @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
  1676
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
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
  1678
				struct e1000_ring *ring)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	struct pci_dev *pdev = adapter->pdev;
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
	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
  1683
					GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
	if (!ring->desc)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
		return -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
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
 * 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
  1692
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
 * Return 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
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
  1697
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
	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
  1699
	int err = -ENOMEM, size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	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
  1702
	tx_ring->buffer_info = vmalloc(size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
	if (!tx_ring->buffer_info)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	memset(tx_ring->buffer_info, 0, size);
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
	/* round up to nearest 4K */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	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
  1709
	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
  1710
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
	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
  1712
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	tx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
	tx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
err:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
	vfree(tx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	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
  1722
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
 * 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
  1727
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
 * Returns 0 on success, negative on failure
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
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
  1732
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	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
  1734
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	int i, size, desc_len, err = -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	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
  1738
	rx_ring->buffer_info = vmalloc(size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
	if (!rx_ring->buffer_info)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
	memset(rx_ring->buffer_info, 0, size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	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
  1744
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
		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
  1746
						sizeof(struct e1000_ps_page),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
						GFP_KERNEL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
		if (!buffer_info->ps_pages)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
			goto err_pages;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
	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
  1753
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
	/* Round up to nearest 4K */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	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
  1756
	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
  1757
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	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
  1759
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
		goto err_pages;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	rx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	rx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	rx_ring->rx_skb_top = NULL;
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
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
err_pages:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	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
  1770
		buffer_info = &rx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
		kfree(buffer_info->ps_pages);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
err:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	vfree(rx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
	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
  1776
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
 * e1000_clean_tx_ring - Free Tx Buffers
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
 * @adapter: board private structure
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
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
  1784
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	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
  1786
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
	unsigned long size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
	unsigned int i;
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
	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
  1791
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		e1000_put_txbuf(adapter, buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
	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
  1796
	memset(tx_ring->buffer_info, 0, size);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
	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
  1799
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	tx_ring->next_to_use = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
	tx_ring->next_to_clean = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
	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
  1804
	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
  1805
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
 * 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
  1809
 * @adapter: board private structure
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
 * Free all transmit software resources
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
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
  1814
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
	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
  1817
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
	e1000_clean_tx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
	vfree(tx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
	tx_ring->buffer_info = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
	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
  1824
			  tx_ring->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
	tx_ring->desc = NULL;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
 * e1000e_free_rx_resources - Free Rx Resources
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
 * @adapter: board private structure
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
 * Free all receive software resources
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
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
  1836
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
	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
  1839
	int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
	e1000_clean_rx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
	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
  1844
		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
  1845
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
	vfree(rx_ring->buffer_info);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	rx_ring->buffer_info = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
	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
  1851
			  rx_ring->dma);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
	rx_ring->desc = NULL;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
 * 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
  1857
 * @adapter: pointer to adapter
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
 * @itr_setting: current adapter->itr
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
 * @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
  1860
 * @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
  1861
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
 *      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
  1863
 *      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
  1864
 *      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
  1865
 *      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
  1866
 *      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
  1867
 *      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
  1868
 *      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
  1869
 *      by the InterruptThrottleRate module parameter.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
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
  1872
				     u16 itr_setting, int packets,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
				     int bytes)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	unsigned int retval = itr_setting;
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
	if (packets == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
		goto update_itr_done;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
	switch (itr_setting) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	case lowest_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
		/* handle TSO and jumbo frames */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
		if (bytes/packets > 8000)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
			retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
		else if ((packets < 5) && (bytes > 512)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
			retval = low_latency;
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
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	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
  1890
		if (bytes > 10000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
			/* this if handles the TSO accounting */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
			if (bytes/packets > 8000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
				retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
			} else if ((packets < 10) || ((bytes/packets) > 1200)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
				retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
			} else if ((packets > 35)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
				retval = lowest_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
		} else if (bytes/packets > 2000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
			retval = bulk_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
		} else if (packets <= 2 && bytes < 512) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
			retval = lowest_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	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
  1906
		if (bytes > 25000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
			if (packets > 35) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
				retval = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
		} else if (bytes < 6000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
			retval = low_latency;
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
		break;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
update_itr_done:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
	return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
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
  1921
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
	u16 current_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
	u32 new_itr = adapter->itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
	/* 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
  1927
	if (adapter->link_speed != SPEED_1000) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
		current_itr = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
		new_itr = 4000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
		goto set_itr_now;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
	adapter->tx_itr = e1000_update_itr(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
				    adapter->tx_itr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
				    adapter->total_tx_packets,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
				    adapter->total_tx_bytes);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
	/* 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
  1938
	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
  1939
		adapter->tx_itr = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
	adapter->rx_itr = e1000_update_itr(adapter,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
				    adapter->rx_itr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
				    adapter->total_rx_packets,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
				    adapter->total_rx_bytes);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
	/* 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
  1946
	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
  1947
		adapter->rx_itr = low_latency;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
	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
  1950
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
	switch (current_itr) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	/* 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
  1953
	case lowest_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
		new_itr = 70000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
	case low_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
		new_itr = 20000; /* aka hwitr = ~200 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
	case bulk_latency:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
		new_itr = 4000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
	default:
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
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
set_itr_now:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	if (new_itr != adapter->itr) {
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
		 * 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
  1970
		 * 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
  1971
		 * increasing
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
		new_itr = new_itr > adapter->itr ?
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
			     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
  1975
			     new_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
		adapter->itr = new_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
		adapter->rx_ring->itr_val = new_itr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
		if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
			adapter->rx_ring->set_itr = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
			ew32(ITR, 1000000000 / (new_itr * 256));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
}
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
 * 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
  1987
 * @adapter: board private structure to initialize
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
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
  1990
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
	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
  1992
	if (!adapter->tx_ring)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	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
  1996
	if (!adapter->rx_ring)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
		goto err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
err:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
	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
  2002
	kfree(adapter->rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
	kfree(adapter->tx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	return -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
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
 * e1000_clean - NAPI Rx polling callback
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
 * @napi: struct associated with this polling callback
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
 * @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
  2011
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
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
  2013
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	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
  2015
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
	struct net_device *poll_dev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	int tx_cleaned = 1, work_done = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	adapter = netdev_priv(poll_dev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	if (adapter->msix_entries &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
	    !(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
  2023
		goto clean_rx;
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
	tx_cleaned = e1000_clean_tx_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
clean_rx:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	adapter->clean_rx(adapter, &work_done, budget);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	if (!tx_cleaned)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
		work_done = budget;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	/* 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
  2034
	if (work_done < budget) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
		if (adapter->itr_setting & 3)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
			e1000_set_itr(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
		napi_complete(napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
		if (!test_bit(__E1000_DOWN, &adapter->state)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
			if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
				ew32(IMS, adapter->rx_ring->ims_val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
			else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
				e1000_irq_enable(adapter);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
	return work_done;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
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
  2050
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
	u32 vfta, index;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
	/* 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
  2056
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
	    (vid == adapter->mng_vlan_id))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
	/* add VID to filter table */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	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
  2063
		index = (vid >> 5) & 0x7F;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
		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
  2065
		vfta |= (1 << (vid & 0x1F));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
		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
  2067
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
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
  2071
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
	u32 vfta, index;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
		e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
	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
  2079
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
		e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	    (vid == adapter->mng_vlan_id)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
		/* release control to f/w */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
		e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
	/* remove VID from filter table */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
	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
  2093
		index = (vid >> 5) & 0x7F;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
		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
  2095
		vfta &= ~(1 << (vid & 0x1F));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
		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
  2097
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
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
  2101
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
	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
  2104
	u16 old_vid = adapter->mng_vlan_id;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
	if (!adapter->vlgrp)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
	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
  2110
		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
  2111
		if (adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
			e1000_vlan_rx_add_vid(netdev, vid);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
			adapter->mng_vlan_id = vid;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
		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
  2118
				(vid != old_vid) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
		    !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
  2120
			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
  2121
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
		adapter->mng_vlan_id = vid;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
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
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
  2128
				   struct vlan_group *grp)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
	u32 ctrl, rctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
		e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	adapter->vlgrp = grp;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	if (grp) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
		/* enable VLAN tag insert/strip */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
		ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
		ctrl |= E1000_CTRL_VME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
		ew32(CTRL, ctrl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
		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
  2145
			/* enable VLAN receive filtering */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
			rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
			rctl &= ~E1000_RCTL_CFIEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
			ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
			e1000_update_mng_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
		/* disable VLAN tag insert/strip */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
		ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
		ctrl &= ~E1000_CTRL_VME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
		ew32(CTRL, ctrl);
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
		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
  2158
			if (adapter->mng_vlan_id !=
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
			    (u16)E1000_MNG_VLAN_NONE) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
				e1000_vlan_rx_kill_vid(netdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
						       adapter->mng_vlan_id);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
				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
  2163
			}
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
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
		e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
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
  2172
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	u16 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
	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
  2176
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	if (!adapter->vlgrp)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	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
  2181
		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
  2182
			continue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
		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
  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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
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
  2188
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	u32 manc, manc2h;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
	if (!(adapter->flags & FLAG_MNG_PT_ENABLED))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	manc = er32(MANC);
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
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	 * 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
  2199
	 * 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
  2200
	 * the packets will be handled on SMBUS
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	manc |= E1000_MANC_EN_MNG2HOST;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
	manc2h = er32(MANC2H);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
#define E1000_MNG2HOST_PORT_623 (1 << 5)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
#define E1000_MNG2HOST_PORT_664 (1 << 6)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
	manc2h |= E1000_MNG2HOST_PORT_623;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
	manc2h |= E1000_MNG2HOST_PORT_664;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
	ew32(MANC2H, manc2h);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	ew32(MANC, manc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
 * 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
  2214
 * @adapter: board private structure
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
 * 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
  2217
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
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
  2219
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	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
  2222
	u64 tdba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	u32 tdlen, tctl, tipg, tarc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
	u32 ipgr1, ipgr2;
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
	/* 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
  2227
	tdba = tx_ring->dma;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	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
  2229
	ew32(TDBAL, (tdba & DMA_BIT_MASK(32)));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
	ew32(TDBAH, (tdba >> 32));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	ew32(TDLEN, tdlen);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
	ew32(TDH, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
	ew32(TDT, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
	tx_ring->head = E1000_TDH;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	tx_ring->tail = E1000_TDT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	/* 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
  2238
	tipg = DEFAULT_82543_TIPG_IPGT_COPPER;          /*  8  */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	ipgr1 = DEFAULT_82543_TIPG_IPGR1;               /*  8  */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	ipgr2 = DEFAULT_82543_TIPG_IPGR2;               /*  6  */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	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
  2243
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /*  7  */
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
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	ew32(TIPG, tipg);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
	/* Set the Tx Interrupt Delay register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
	ew32(TIDV, adapter->tx_int_delay);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
	/* Tx irq moderation */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
	ew32(TADV, adapter->tx_abs_int_delay);
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
	/* Program the Transmit Control Register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	tctl = er32(TCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
	tctl &= ~E1000_TCTL_CT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	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
  2261
		tarc = er32(TARC(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
		 * 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
  2264
		 * gigabit link later
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
#define SPEED_MODE_BIT (1 << 21)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
		tarc |= SPEED_MODE_BIT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
		ew32(TARC(0), tarc);
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
	/* errata: program both queues to unweighted RR */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
	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
  2273
		tarc = er32(TARC(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
		tarc |= 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
		ew32(TARC(0), tarc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
		tarc = er32(TARC(1));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
		tarc |= 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
		ew32(TARC(1), tarc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	/* Setup Transmit Descriptor Settings for eop descriptor */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
	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
  2283
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
	/* 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
  2285
	if (adapter->tx_int_delay)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	/* enable Report Status bit */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	adapter->txd_cmd |= E1000_TXD_CMD_RS;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	ew32(TCTL, tctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	e1000e_config_collision_dist(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	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
  2296
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
 * 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
  2300
 * @adapter: Board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
#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
  2303
			   (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
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
  2305
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	u32 rctl, rfctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	u32 psrctl = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	u32 pages = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	/* Program MC offset vector base */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
		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
  2316
		(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
  2317
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	/* Do not Store bad packets */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
	rctl &= ~E1000_RCTL_SBP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2320
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2321
	/* Enable Long Packet receive */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2322
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2323
		rctl &= ~E1000_RCTL_LPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2324
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2325
		rctl |= E1000_RCTL_LPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2326
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2327
	/* 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
  2328
	 * 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
  2329
	 * host memory when this is enabled
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2330
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2331
	if (adapter->flags2 & FLAG2_CRC_STRIPPING)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2332
		rctl |= E1000_RCTL_SECRC;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2333
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2334
	/* 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
  2335
	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
  2336
		u16 phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2337
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2338
		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
  2339
		phy_data &= 0xfff8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2340
		phy_data |= (1 << 2);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2341
		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
  2342
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2343
		e1e_rphy(hw, 22, &phy_data);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2344
		phy_data &= 0x0fff;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2345
		phy_data |= (1 << 14);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2346
		e1e_wphy(hw, 0x10, 0x2823);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2347
		e1e_wphy(hw, 0x11, 0x0003);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2348
		e1e_wphy(hw, 22, phy_data);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2351
	/* Setup buffer sizes */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2352
	rctl &= ~E1000_RCTL_SZ_4096;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2353
	rctl |= E1000_RCTL_BSEX;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2354
	switch (adapter->rx_buffer_len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2355
	case 2048:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2356
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2357
		rctl |= E1000_RCTL_SZ_2048;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2358
		rctl &= ~E1000_RCTL_BSEX;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2359
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2360
	case 4096:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2361
		rctl |= E1000_RCTL_SZ_4096;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2362
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2363
	case 8192:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2364
		rctl |= E1000_RCTL_SZ_8192;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2365
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2366
	case 16384:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2367
		rctl |= E1000_RCTL_SZ_16384;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2368
		break;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2371
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2372
	 * 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
  2373
	 * 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
  2374
	 * 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
  2375
	 * 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
  2376
	 * 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
  2377
	 * sized to hold the largest protocol header.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2378
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2379
	 * 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
  2380
	 * 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
  2381
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2382
	 * 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
  2383
	 * 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
  2384
	 * per packet.
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
	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2387
	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
  2388
	    (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2389
		adapter->rx_ps_pages = pages;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2390
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2391
		adapter->rx_ps_pages = 0;
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
	if (adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2394
		/* Configure extra packet-split registers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2395
		rfctl = er32(RFCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2396
		rfctl |= E1000_RFCTL_EXTEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2397
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2398
		 * 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
  2399
		 * 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
  2400
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2401
		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2402
			  E1000_RFCTL_NEW_IPV6_EXT_DIS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2403
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2404
		ew32(RFCTL, rfctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2405
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2406
		/* Enable Packet split descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2407
		rctl |= E1000_RCTL_DTYP_PS;
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
		psrctl |= adapter->rx_ps_bsize0 >>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2410
			E1000_PSRCTL_BSIZE0_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2411
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2412
		switch (adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2413
		case 3:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2414
			psrctl |= PAGE_SIZE <<
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2415
				E1000_PSRCTL_BSIZE3_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2416
		case 2:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2417
			psrctl |= PAGE_SIZE <<
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2418
				E1000_PSRCTL_BSIZE2_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2419
		case 1:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2420
			psrctl |= PAGE_SIZE >>
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2421
				E1000_PSRCTL_BSIZE1_SHIFT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2422
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2423
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2424
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2425
		ew32(PSRCTL, psrctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2426
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2427
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2428
	ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2429
	/* 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
  2430
	adapter->flags &= ~FLAG_RX_RESTART_NOW;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2431
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2432
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2433
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2434
 * 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
  2435
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2436
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2437
 * 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
  2438
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2439
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
  2440
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2441
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2442
	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
  2443
	u64 rdba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2444
	u32 rdlen, rctl, rxcsum, ctrl_ext;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2445
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2446
	if (adapter->rx_ps_pages) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2447
		/* this is a 32 byte descriptor */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2448
		rdlen = rx_ring->count *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2449
			sizeof(union e1000_rx_desc_packet_split);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2450
		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
  2451
		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
  2452
	} 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
  2453
		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
  2454
		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
  2455
		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
  2456
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2457
		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
  2458
		adapter->clean_rx = e1000_clean_rx_irq;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2459
		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
  2460
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2461
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2462
	/* disable receives while setting up the descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2463
	rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2464
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2465
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2466
	msleep(10);
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
	/* set the Receive Delay Timer Register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2469
	ew32(RDTR, adapter->rx_int_delay);
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
	/* irq moderation */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2472
	ew32(RADV, adapter->rx_abs_int_delay);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2473
	if (adapter->itr_setting != 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2474
		ew32(ITR, 1000000000 / (adapter->itr * 256));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2475
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2476
	ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2477
	/* Auto-Mask interrupts upon ICR access */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2478
	ctrl_ext |= E1000_CTRL_EXT_IAME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2479
	ew32(IAM, 0xffffffff);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2480
	ew32(CTRL_EXT, ctrl_ext);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2481
	e1e_flush();
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
	 * 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
  2485
	 * 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
  2486
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2487
	rdba = rx_ring->dma;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2488
	ew32(RDBAL, (rdba & DMA_BIT_MASK(32)));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2489
	ew32(RDBAH, (rdba >> 32));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2490
	ew32(RDLEN, rdlen);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2491
	ew32(RDH, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2492
	ew32(RDT, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2493
	rx_ring->head = E1000_RDH;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2494
	rx_ring->tail = E1000_RDT;
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
	/* 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
  2497
	rxcsum = er32(RXCSUM);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2498
	if (adapter->flags & FLAG_RX_CSUM_ENABLED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2499
		rxcsum |= E1000_RXCSUM_TUOFL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2500
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2501
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2502
		 * 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
  2503
		 * used in conjunction with packet-split.
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
			rxcsum |= E1000_RXCSUM_IPPCSE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2507
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2508
		rxcsum &= ~E1000_RXCSUM_TUOFL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2509
		/* 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
  2510
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2511
	ew32(RXCSUM, rxcsum);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2512
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2513
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2514
	 * 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
  2515
	 * 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
  2516
	 * 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
  2517
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2518
	if (adapter->flags & FLAG_HAS_ERT) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2519
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2520
			u32 rxdctl = er32(RXDCTL(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2521
			ew32(RXDCTL(0), rxdctl | 0x3);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2522
			ew32(ERT, E1000_ERT_2048 | (1 << 13));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2523
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2524
			 * With jumbo frames and early-receive enabled,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2525
			 * excessive C-state transition latencies result in
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2526
			 * dropped transactions.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2527
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2528
			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
  2529
						  adapter->netdev->name, 55);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2530
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2531
			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
  2532
						  adapter->netdev->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2533
						  PM_QOS_DEFAULT_VALUE);
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
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2536
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2537
	/* Enable Receives */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2538
	ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2539
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2540
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
 *  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
  2543
 *  @hw: pointer to the HW structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2544
 *  @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
  2545
 *  @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
  2546
 *  @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
  2547
 *  @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
  2548
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2549
 *  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
  2550
 *  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
  2551
 *  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
  2552
 *  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
  2553
 *  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
  2554
 *  function.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2555
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2556
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
  2557
				      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
  2558
				      u32 rar_count)
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
	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
  2561
				        rar_used_count, rar_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2562
}
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2565
 * 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
  2566
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2567
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2568
 * 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
  2569
 * 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
  2570
 * 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
  2571
 * promiscuous mode, and all-multi behavior.
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
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
  2574
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2575
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2576
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2577
	struct e1000_mac_info *mac = &hw->mac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2578
	struct dev_mc_list *mc_ptr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2579
	u8  *mta_list;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2580
	u32 rctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2581
	int i;
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
	/* Check for Promiscuous and All Multicast modes */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2584
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2585
	rctl = er32(RCTL);
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
	if (netdev->flags & IFF_PROMISC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2588
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2589
		rctl &= ~E1000_RCTL_VFE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2590
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2591
		if (netdev->flags & IFF_ALLMULTI) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2592
			rctl |= E1000_RCTL_MPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2593
			rctl &= ~E1000_RCTL_UPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2594
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2595
			rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2596
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2597
		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
  2598
			rctl |= E1000_RCTL_VFE;
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
	ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2602
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2603
	if (netdev->mc_count) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2604
		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
  2605
		if (!mta_list)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2606
			return;
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
		/* prepare a packed array of only addresses. */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2609
		mc_ptr = netdev->mc_list;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2610
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2611
		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
  2612
			if (!mc_ptr)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2613
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2614
			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
  2615
			       ETH_ALEN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2616
			mc_ptr = mc_ptr->next;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2617
		}
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
		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
  2620
					  mac->rar_entry_count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2621
		kfree(mta_list);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2622
	} else {
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
		 * 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
  2625
		 * 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
  2626
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2627
		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
  2628
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2629
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2630
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
 * 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
  2633
 * @adapter: private board structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2634
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2635
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
  2636
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2637
	e1000_set_multi(adapter->netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2638
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2639
	e1000_restore_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2640
	e1000_init_manageability(adapter);
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
	e1000_configure_tx(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2643
	e1000_setup_rctl(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2644
	e1000_configure_rx(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2645
	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
  2646
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2647
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2648
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2649
 * 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
  2650
 * @adapter: address of board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2651
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2652
 * 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
  2653
 * 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
  2654
 * *** 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
  2655
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2656
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
  2657
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2658
	if (adapter->hw.phy.ops.power_up)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2659
		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
  2660
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2661
	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
  2662
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2663
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2664
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2665
 * 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
  2666
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2667
 * 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
  2668
 * 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
  2669
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2670
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
  2671
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2672
	/* WoL is enabled */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2673
	if (adapter->wol)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2674
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2675
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2676
	if (adapter->hw.phy.ops.power_down)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2677
		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
  2678
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2679
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2680
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2681
 * 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
  2682
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2683
 * 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
  2684
 * 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
  2685
 * 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
  2686
 * properly configured for Rx, Tx etc.
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
void e1000e_reset(struct e1000_adapter *adapter)
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
	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
  2691
	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
  2692
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2693
	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
  2694
	u32 pba = adapter->pba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2695
	u16 hwm;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2696
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2697
	/* reset Packet Buffer Allocation to default */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2698
	ew32(PBA, pba);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2699
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2700
	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
  2701
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2702
		 * 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
  2703
		 * 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
  2704
		 * 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
  2705
		 * 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
  2706
		 * 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
  2707
		 * expressed in KB.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2708
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2709
		pba = er32(PBA);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2710
		/* 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
  2711
		tx_space = pba >> 16;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2712
		/* 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
  2713
		pba &= 0xffff;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2714
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2715
		 * 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
  2716
		 * 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
  2717
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2718
		min_tx_space = (adapter->max_frame_size +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2719
				sizeof(struct e1000_tx_desc) -
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2720
				ETH_FCS_LEN) * 2;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2721
		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
  2722
		min_tx_space >>= 10;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2723
		/* 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
  2724
		min_rx_space = adapter->max_frame_size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2725
		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
  2726
		min_rx_space >>= 10;
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
		 * 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
  2730
		 * 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
  2731
		 * 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
  2732
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2733
		if ((tx_space < min_tx_space) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2734
		    ((min_tx_space - tx_space) < pba)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2735
			pba -= min_tx_space - tx_space;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2736
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2737
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2738
			 * 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
  2739
			 * adjustment or use Early Receive if available
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2740
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2741
			if ((pba < min_rx_space) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2742
			    (!(adapter->flags & FLAG_HAS_ERT)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2743
				/* ERT enabled in e1000_configure_rx */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2744
				pba = min_rx_space;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2745
		}
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
		ew32(PBA, pba);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2748
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2749
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2750
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
	 * flow control settings
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
	 * 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
  2755
	 * (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
  2756
	 * Set it to the lower of:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2757
	 * - 90% of the Rx FIFO size, and
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2758
	 * - 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
  2759
	 *   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
  2760
	 * - 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
  2761
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2762
	if (hw->mac.type == e1000_pchlan) {
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
		 * 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
  2765
		 * 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
  2766
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2767
		if (adapter->netdev->mtu > ETH_DATA_LEN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2768
			fc->high_water = 0x3500;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2769
			fc->low_water  = 0x1500;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2770
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2771
			fc->high_water = 0x5000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2772
			fc->low_water  = 0x3000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2773
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2774
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2775
		if ((adapter->flags & FLAG_HAS_ERT) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2776
		    (adapter->netdev->mtu > ETH_DATA_LEN))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2777
			hwm = min(((pba << 10) * 9 / 10),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2778
				  ((pba << 10) - (E1000_ERT_2048 << 3)));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2779
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2780
			hwm = min(((pba << 10) * 9 / 10),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2781
				  ((pba << 10) - adapter->max_frame_size));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2782
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2783
		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
  2784
		fc->low_water = fc->high_water - 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2785
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2786
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2787
	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
  2788
		fc->pause_time = 0xFFFF;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2789
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2790
		fc->pause_time = E1000_FC_PAUSE_TIME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2791
	fc->send_xon = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2792
	fc->current_mode = fc->requested_mode;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2793
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2794
	/* 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
  2795
	mac->ops.reset_hw(hw);
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
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2798
	 * 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
  2799
	 * that the network interface is in control
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
	if (adapter->flags & FLAG_HAS_AMT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2802
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2803
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2804
	ew32(WUC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2805
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2806
		e1e_wphy(&adapter->hw, BM_WUC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2807
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2808
	if (mac->ops.init_hw(hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2809
		e_err("Hardware Error\n");
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
	/* 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
  2812
	if (hw->mac.type == e1000_pchlan)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2813
		ew32(FCRTV_PCH, 0x1000);
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
	e1000_update_mng_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2816
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2817
	/* 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
  2818
	ew32(VET, ETH_P_8021Q);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2819
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2820
	e1000e_reset_adaptive(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2821
	e1000_get_phy_info(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2822
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2823
	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
  2824
	    !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2825
		u16 phy_data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2826
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2827
		 * 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
  2828
		 * 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
  2829
		 * different we would do if it failed
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
		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
  2832
		phy_data &= ~IGP02E1000_PM_SPD;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2833
		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
  2834
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2835
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2836
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2837
int e1000e_up(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2838
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2839
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2840
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2841
	/* 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
  2842
	if (adapter->flags & FLAG_HAS_ERT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2843
		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
  2844
		                       adapter->netdev->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2845
				       PM_QOS_DEFAULT_VALUE);
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
	/* 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
  2848
	e1000_configure(adapter);
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
	clear_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2851
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2852
	napi_enable(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2853
	if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2854
		e1000_configure_msix(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2855
	e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2856
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2857
	netif_wake_queue(adapter->netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2858
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2859
	/* 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
  2860
	ew32(ICS, E1000_ICS_LSC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2861
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2862
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2863
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2864
void e1000e_down(struct e1000_adapter *adapter)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2865
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2866
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2867
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2868
	u32 tctl, rctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2869
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2870
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2871
	 * 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
  2872
	 * reschedule our watchdog timer
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2873
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2874
	set_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2875
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2876
	/* disable receives in the hardware */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2877
	rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2878
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2879
	/* flush and sleep below */
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
	netif_stop_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2882
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2883
	/* disable transmits in the hardware */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2884
	tctl = er32(TCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2885
	tctl &= ~E1000_TCTL_EN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2886
	ew32(TCTL, tctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2887
	/* 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
  2888
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2889
	msleep(10);
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
	napi_disable(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2892
	e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2893
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2894
	del_timer_sync(&adapter->watchdog_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2895
	del_timer_sync(&adapter->phy_info_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2896
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2897
	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
  2898
	netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2899
	adapter->link_speed = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2900
	adapter->link_duplex = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2901
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2902
	if (!pci_channel_offline(adapter->pdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2903
		e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2904
	e1000_clean_tx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2905
	e1000_clean_rx_ring(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2906
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2907
	if (adapter->flags & FLAG_HAS_ERT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2908
		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
  2909
		                          adapter->netdev->name);
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
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2912
	 * 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
  2913
	 * pci_disable_device here.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2914
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2915
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2916
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2917
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
  2918
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2919
	might_sleep();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2920
	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
  2921
		msleep(1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2922
	e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2923
	e1000e_up(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2924
	clear_bit(__E1000_RESETTING, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2925
}
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2928
 * 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
  2929
 * @adapter: board private structure to initialize
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2930
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2931
 * 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
  2932
 * 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
  2933
 * OS network device settings (MTU size).
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
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
  2936
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2937
	struct net_device *netdev = adapter->netdev;
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
	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
  2940
	adapter->rx_ps_bsize0 = 128;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2941
	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
  2942
	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
  2943
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2944
	e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2945
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2946
	if (e1000_alloc_queues(adapter))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2947
		return -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2948
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2949
	/* 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
  2950
	e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2951
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2952
	set_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2953
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2954
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2955
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2956
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2957
 * e1000_intr_msi_test - Interrupt Handler
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2958
 * @irq: interrupt number
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2959
 * @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
  2960
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2961
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
  2962
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2963
	struct net_device *netdev = data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2964
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2965
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2966
	u32 icr = er32(ICR);
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
	e_dbg("icr is %08X\n", icr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2969
	if (icr & E1000_ICR_RXSEQ) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2970
		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2971
		wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2972
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2973
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2974
	return IRQ_HANDLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2975
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2976
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2977
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2978
 * 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
  2979
 * @adapter: board private struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2980
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2981
 * code flow taken from tg3.c
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2982
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2983
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
  2984
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2985
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2986
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2987
	int err;
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
	/* 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
  2990
	/* clear any pending events */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2991
	er32(ICR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2992
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2993
	/* 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
  2994
	e1000_free_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2995
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2996
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2997
	/* 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
  2998
	 * MSI irq handler will unset this flag */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2999
	adapter->flags |= FLAG_MSI_TEST_FAILED;
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
	err = pci_enable_msi(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3002
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3003
		goto msi_test_failed;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3004
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3005
	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
  3006
			  netdev->name, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3007
	if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3008
		pci_disable_msi(adapter->pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3009
		goto msi_test_failed;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3010
	}
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
	wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3013
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3014
	e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3015
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3016
	/* 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
  3017
	ew32(ICS, E1000_ICS_RXSEQ);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3018
	e1e_flush();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3019
	msleep(50);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3020
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3021
	e1000_irq_disable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3022
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3023
	rmb();
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
	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3026
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3027
		err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3028
		e_info("MSI interrupt test failed!\n");
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3031
	free_irq(adapter->pdev->irq, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3032
	pci_disable_msi(adapter->pdev);
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
	if (err == -EIO)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3035
		goto msi_test_failed;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3036
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3037
	/* okay so the test worked, restore settings */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3038
	e_dbg("MSI interrupt test succeeded!\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3039
msi_test_failed:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3040
	e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3041
	e1000_request_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3042
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3043
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3044
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
 * 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
  3047
 * @adapter: board private struct
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
 * 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
  3050
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3051
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
  3052
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3053
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3054
	u16 pci_cmd;
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
	if (!(adapter->flags & FLAG_MSI_ENABLED))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3057
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3058
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3059
	/* 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
  3060
	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
  3061
	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
  3062
			      pci_cmd & ~PCI_COMMAND_SERR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3063
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3064
	err = e1000_test_msi_interrupt(adapter);
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
	/* restore previous setting of command word */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3067
	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
  3068
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3069
	/* success ! */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3070
	if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3071
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3072
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3073
	/* EIO means MSI test failed */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3074
	if (err != -EIO)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3075
		return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3076
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3077
	/* back to INTx mode */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3078
	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
  3079
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3080
	e1000_free_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3081
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3082
	err = e1000_request_irq(adapter);
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
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3085
}
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3088
 * 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
  3089
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3090
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3091
 * 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
  3092
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3093
 * 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
  3094
 * 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
  3095
 * 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
  3096
 * 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
  3097
 * 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
  3098
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3099
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
  3100
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3101
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3102
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3103
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3104
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3105
	/* disallow open during test */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3106
	if (test_bit(__E1000_TESTING, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3107
		return -EBUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3108
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3109
	netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3110
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3111
	/* allocate transmit descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3112
	err = e1000e_setup_tx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3113
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3114
		goto err_setup_tx;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3115
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3116
	/* allocate receive descriptors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3117
	err = e1000e_setup_rx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3118
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3119
		goto err_setup_rx;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3120
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3121
	e1000e_power_up_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3122
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3123
	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
  3124
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3125
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3126
		e1000_update_mng_vlan(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3127
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 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
  3130
	 * interface is now open
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
	if (adapter->flags & FLAG_HAS_AMT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3133
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3134
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3135
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3136
	 * 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
  3137
	 * 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
  3138
	 * 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
  3139
	 * clean_rx handler before we do so.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3140
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3141
	e1000_configure(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3142
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3143
	err = e1000_request_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3144
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3145
		goto err_req_irq;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3146
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3147
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3148
	 * 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
  3149
	 * 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
  3150
	 * interrupt now
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3151
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3152
	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
  3153
		err = e1000_test_msi(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3154
		if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3155
			e_err("Interrupt allocation failed\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3156
			goto err_req_irq;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3157
		}
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
	/* 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
  3161
	clear_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3162
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3163
	napi_enable(&adapter->napi);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3164
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3165
	e1000_irq_enable(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3166
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3167
	netif_start_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3168
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3169
	/* 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
  3170
	ew32(ICS, E1000_ICS_LSC);
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
	return 0;
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
err_req_irq:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3175
	e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3176
	e1000_power_down_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3177
	e1000e_free_rx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3178
err_setup_rx:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3179
	e1000e_free_tx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3180
err_setup_tx:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3181
	e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3182
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3183
	return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3184
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3185
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
 * e1000_close - Disables a network interface
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3188
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3189
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3190
 * 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
  3191
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3192
 * 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
  3193
 * 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
  3194
 * 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
  3195
 * 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
  3196
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3197
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
  3198
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3199
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3200
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3201
	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
  3202
	e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3203
	e1000_power_down_phy(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3204
	e1000_free_irq(adapter);
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
	e1000e_free_tx_resources(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3207
	e1000e_free_rx_resources(adapter);
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
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3210
	 * 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
  3211
	 * 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
  3212
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3213
	if ((adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3214
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3215
	     !(adapter->vlgrp &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3216
	       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
  3217
		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
  3218
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
	 * 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
  3221
	 * interface is now closed
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3222
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3223
	if (adapter->flags & FLAG_HAS_AMT)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3224
		e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3225
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3226
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3227
}
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
 * 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
  3230
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3231
 * @p: pointer to an address structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3232
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3233
 * Returns 0 on success, negative on failure
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
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
  3236
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3237
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3238
	struct sockaddr *addr = p;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3239
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3240
	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
  3241
		return -EADDRNOTAVAIL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3242
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3243
	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
  3244
	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
  3245
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3246
	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
  3247
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3248
	if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3249
		/* activate the work around */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3250
		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
  3251
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
		 * 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
  3254
		 * 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
  3255
		 * 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
  3256
		 * 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
  3257
		 * 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
  3258
		 * RAR[14]
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3259
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3260
		e1000e_rar_set(&adapter->hw,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3261
			      adapter->hw.mac.addr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3262
			      adapter->hw.mac.rar_entry_count - 1);
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
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3266
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3267
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
 * 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
  3270
 * @work: pointer to our work struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3271
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3272
 * 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
  3273
 * 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
  3274
 * 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
  3275
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3276
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
  3277
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3278
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3279
					struct e1000_adapter, update_phy_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3280
	e1000_get_phy_info(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3281
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3282
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3283
/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3284
 * 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
  3285
 * the phy
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3286
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3287
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
  3288
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3289
	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
  3290
	schedule_work(&adapter->update_phy_task);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3293
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3294
 * 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
  3295
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3296
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3297
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
  3298
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3299
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3300
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3301
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3302
	u16 phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3303
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
	 * 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
  3306
	 * connection is down.
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
	if (adapter->link_speed == 0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3309
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3310
	if (pci_channel_offline(pdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3311
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3312
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3313
	adapter->stats.crcerrs += er32(CRCERRS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3314
	adapter->stats.gprc += er32(GPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3315
	adapter->stats.gorc += er32(GORCL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3316
	er32(GORCH); /* Clear gorc */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3317
	adapter->stats.bprc += er32(BPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3318
	adapter->stats.mprc += er32(MPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3319
	adapter->stats.roc += er32(ROC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3320
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3321
	adapter->stats.mpc += er32(MPC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3322
	if ((hw->phy.type == e1000_phy_82578) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3323
	    (hw->phy.type == e1000_phy_82577)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3324
		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
  3325
		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
  3326
			adapter->stats.scc += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3327
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3328
		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
  3329
		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
  3330
			adapter->stats.ecol += phy_data;
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
		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
  3333
		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
  3334
			adapter->stats.mcc += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3335
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3336
		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
  3337
		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
  3338
			adapter->stats.latecol += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3339
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3340
		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
  3341
		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
  3342
			adapter->stats.dc += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3343
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3344
		adapter->stats.scc += er32(SCC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3345
		adapter->stats.ecol += er32(ECOL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3346
		adapter->stats.mcc += er32(MCC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3347
		adapter->stats.latecol += er32(LATECOL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3348
		adapter->stats.dc += er32(DC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3349
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3350
	adapter->stats.xonrxc += er32(XONRXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3351
	adapter->stats.xontxc += er32(XONTXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3352
	adapter->stats.xoffrxc += er32(XOFFRXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3353
	adapter->stats.xofftxc += er32(XOFFTXC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3354
	adapter->stats.gptc += er32(GPTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3355
	adapter->stats.gotc += er32(GOTCL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3356
	er32(GOTCH); /* Clear gotc */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3357
	adapter->stats.rnbc += er32(RNBC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3358
	adapter->stats.ruc += er32(RUC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3359
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3360
	adapter->stats.mptc += er32(MPTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3361
	adapter->stats.bptc += er32(BPTC);
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
	/* used for adaptive IFS */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3364
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3365
	hw->mac.tx_packet_delta = er32(TPT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3366
	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
  3367
	if ((hw->phy.type == e1000_phy_82578) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3368
	    (hw->phy.type == e1000_phy_82577)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3369
		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
  3370
		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
  3371
			hw->mac.collision_delta = phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3372
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3373
		hw->mac.collision_delta = er32(COLC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3374
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3375
	adapter->stats.colc += hw->mac.collision_delta;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3376
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3377
	adapter->stats.algnerrc += er32(ALGNERRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3378
	adapter->stats.rxerrc += er32(RXERRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3379
	if ((hw->phy.type == e1000_phy_82578) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3380
	    (hw->phy.type == e1000_phy_82577)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3381
		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
  3382
		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
  3383
			adapter->stats.tncrs += phy_data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3384
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3385
		if ((hw->mac.type != e1000_82574) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3386
		    (hw->mac.type != e1000_82583))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3387
			adapter->stats.tncrs += er32(TNCRS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3388
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3389
	adapter->stats.cexterr += er32(CEXTERR);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3390
	adapter->stats.tsctc += er32(TSCTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3391
	adapter->stats.tsctfc += er32(TSCTFC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3392
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3393
	/* Fill out the OS statistics structure */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3394
	netdev->stats.multicast = adapter->stats.mprc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3395
	netdev->stats.collisions = adapter->stats.colc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3396
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3397
	/* Rx Errors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3398
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
	 * 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
  3401
	 * 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
  3402
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3403
	netdev->stats.rx_errors = adapter->stats.rxerrc +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3404
		adapter->stats.crcerrs + adapter->stats.algnerrc +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3405
		adapter->stats.ruc + adapter->stats.roc +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3406
		adapter->stats.cexterr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3407
	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
  3408
					      adapter->stats.roc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3409
	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
  3410
	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
  3411
	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
  3412
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3413
	/* Tx Errors */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3414
	netdev->stats.tx_errors = adapter->stats.ecol +
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3415
				       adapter->stats.latecol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3416
	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
  3417
	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
  3418
	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
  3419
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3420
	/* Tx Dropped needs to be maintained elsewhere */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3421
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3422
	/* Management Stats */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3423
	adapter->stats.mgptc += er32(MGTPTC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3424
	adapter->stats.mgprc += er32(MGTPRC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3425
	adapter->stats.mgpdc += er32(MGTPDC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3426
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3427
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
 * 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
  3430
 * @adapter: board private structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3431
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3432
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
  3433
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3434
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3435
	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
  3436
	int ret_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3437
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3438
	if ((er32(STATUS) & E1000_STATUS_LU) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3439
	    (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
  3440
		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
  3441
		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
  3442
		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
  3443
		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
  3444
		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
  3445
		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
  3446
		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
  3447
		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
  3448
		if (ret_val)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3449
			e_warn("Error reading PHY register\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3450
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3451
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3452
		 * 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
  3453
		 * Set values to typical power-on defaults
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3454
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3455
		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
  3456
		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
  3457
			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3458
			     BMSR_ERCAP);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3459
		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
  3460
				  ADVERTISE_ALL | ADVERTISE_CSMA);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3461
		phy->lpa = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3462
		phy->expansion = EXPANSION_ENABLENPAGE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3463
		phy->ctrl1000 = ADVERTISE_1000FULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3464
		phy->stat1000 = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3465
		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
  3466
	}
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3469
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
  3470
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3471
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3472
	u32 ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3473
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3474
	/* 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
  3475
	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
  3476
	       "Flow Control: %s\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3477
	       adapter->netdev->name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3478
	       adapter->link_speed,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3479
	       (adapter->link_duplex == FULL_DUPLEX) ?
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3480
	                        "Full Duplex" : "Half Duplex",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3481
	       ((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
  3482
	                        "RX/TX" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3483
	       ((ctrl & E1000_CTRL_RFCE) ? "RX" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3484
	       ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3485
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3486
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3487
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
  3488
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3489
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3490
	bool link_active = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3491
	s32 ret_val = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3492
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3493
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3494
	 * 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
  3495
	 * 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
  3496
	 * 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
  3497
	 * for copper adapters ONLY
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
	switch (hw->phy.media_type) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3500
	case e1000_media_type_copper:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3501
		if (hw->mac.get_link_status) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3502
			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
  3503
			link_active = !hw->mac.get_link_status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3504
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3505
			link_active = 1;
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
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3508
	case e1000_media_type_fiber:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3509
		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
  3510
		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3511
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3512
	case e1000_media_type_internal_serdes:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3513
		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
  3514
		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
  3515
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3516
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3517
	case e1000_media_type_unknown:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3518
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3519
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3520
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3521
	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
  3522
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3523
		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3524
		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
  3525
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3526
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3527
	return link_active;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3528
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3529
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3530
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
  3531
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3532
	/* make sure the receive unit is started */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3533
	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3534
	    (adapter->flags & FLAG_RX_RESTART_NOW)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3535
		struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3536
		u32 rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3537
		ew32(RCTL, rctl | E1000_RCTL_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3538
		adapter->flags &= ~FLAG_RX_RESTART_NOW;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3539
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3540
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3541
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3542
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3543
 * e1000_watchdog - Timer Call-back
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3544
 * @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
  3545
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3546
static void e1000_watchdog(unsigned long data)
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
	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
  3549
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3550
	/* Do the rest outside of interrupt context */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3551
	schedule_work(&adapter->watchdog_task);
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
	/* TODO: make this use queue_delayed_work() */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3554
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3555
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3556
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
  3557
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3558
	struct e1000_adapter *adapter = container_of(work,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3559
					struct e1000_adapter, watchdog_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3560
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3561
	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
  3562
	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
  3563
	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
  3564
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3565
	u32 link, tctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3566
	int tx_pending = 0;
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
	link = e1000_has_link(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3569
	if ((netif_carrier_ok(netdev)) && link) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3570
		e1000e_enable_receives(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3571
		goto link_up;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3574
	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3575
	    (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
  3576
		e1000_update_mng_vlan(adapter);
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
	if (link) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3579
		if (!netif_carrier_ok(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3580
			bool txb2b = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3581
			/* update snapshot of PHY registers on LSC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3582
			e1000_phy_read_status(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3583
			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
  3584
						   &adapter->link_speed,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3585
						   &adapter->link_duplex);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3586
			e1000_print_link_info(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3587
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3588
			 * 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
  3589
			 * 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
  3590
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3591
			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
  3592
			     hw->phy.type == e1000_phy_bm) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3593
			    (hw->mac.autoneg == true) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3594
			    (adapter->link_speed == SPEED_10 ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3595
			     adapter->link_speed == SPEED_100) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3596
			    (adapter->link_duplex == HALF_DUPLEX)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3597
				u16 autoneg_exp;
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
				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
  3600
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3601
				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
  3602
					e_info("Autonegotiated half duplex but"
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3603
					       " link partner cannot autoneg. "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3604
					       " Try forcing full duplex if "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3605
					       "link gets many collisions.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3606
			}
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
			 * 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
  3610
			 * and adjust the timeout factor
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3611
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3612
			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
  3613
			adapter->tx_timeout_factor = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3614
			switch (adapter->link_speed) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3615
			case SPEED_10:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3616
				txb2b = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3617
				netdev->tx_queue_len = 10;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3618
				adapter->tx_timeout_factor = 16;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3619
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3620
			case SPEED_100:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3621
				txb2b = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3622
				netdev->tx_queue_len = 100;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3623
				adapter->tx_timeout_factor = 10;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3624
				break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3625
			}
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
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3628
			 * workaround: re-program speed mode bit after
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3629
			 * link-up event
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3630
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3631
			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
  3632
			    !txb2b) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3633
				u32 tarc0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3634
				tarc0 = er32(TARC(0));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3635
				tarc0 &= ~SPEED_MODE_BIT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3636
				ew32(TARC(0), tarc0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3637
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3638
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3639
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3640
			 * 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
  3641
			 * some hardware issues
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3642
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3643
			if (!(adapter->flags & FLAG_TSO_FORCE)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3644
				switch (adapter->link_speed) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3645
				case SPEED_10:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3646
				case SPEED_100:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3647
					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
  3648
					netdev->features &= ~NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3649
					netdev->features &= ~NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3650
					break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3651
				case SPEED_1000:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3652
					netdev->features |= NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3653
					netdev->features |= NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3654
					break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3655
				default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3656
					/* oops */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3657
					break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3658
				}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3659
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3660
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3661
			/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3662
			 * 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
  3663
			 * after setting TARC(0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3664
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3665
			tctl = er32(TCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3666
			tctl |= E1000_TCTL_EN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3667
			ew32(TCTL, tctl);
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
                        /*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3670
			 * Perform any post-link-up configuration before
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3671
			 * reporting link up.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3672
			 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3673
			if (phy->ops.cfg_on_link_up)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3674
				phy->ops.cfg_on_link_up(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3675
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3676
			netif_carrier_on(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3677
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3678
			if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3679
				mod_timer(&adapter->phy_info_timer,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3680
					  round_jiffies(jiffies + 2 * HZ));
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
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3683
		if (netif_carrier_ok(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3684
			adapter->link_speed = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3685
			adapter->link_duplex = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3686
			/* Link status message must follow this format */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3687
			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
  3688
			       adapter->netdev->name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3689
			netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3690
			if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3691
				mod_timer(&adapter->phy_info_timer,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3692
					  round_jiffies(jiffies + 2 * HZ));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3693
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3694
			if (adapter->flags & FLAG_RX_NEEDS_RESTART)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3695
				schedule_work(&adapter->reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3696
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3697
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3698
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3699
link_up:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3700
	e1000e_update_stats(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3701
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3702
	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
  3703
	adapter->tpt_old = adapter->stats.tpt;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3704
	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
  3705
	adapter->colc_old = adapter->stats.colc;
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
	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
  3708
	adapter->gorc_old = adapter->stats.gorc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3709
	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
  3710
	adapter->gotc_old = adapter->stats.gotc;
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
	e1000e_update_adaptive(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3713
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3714
	if (!netif_carrier_ok(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3715
		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
  3716
			       tx_ring->count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3717
		if (tx_pending) {
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
			 * 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
  3720
			 * 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
  3721
			 * 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
  3722
			 * (Do the reset outside of interrupt context).
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
			adapter->tx_timeout_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3725
			schedule_work(&adapter->reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3726
			/* return immediately since reset is imminent */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3727
			return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3728
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3729
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3730
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3731
	/* 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
  3732
	if (adapter->msix_entries)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3733
		ew32(ICS, adapter->rx_ring->ims_val);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3734
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3735
		ew32(ICS, E1000_ICS_RXDMT0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3736
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3737
	/* 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
  3738
	adapter->detect_tx_hung = 1;
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
	 * 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
  3742
	 * 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
  3743
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3744
	if (e1000e_get_laa_state_82571(hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3745
		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
  3746
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3747
	/* Reset the timer */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3748
	if (!test_bit(__E1000_DOWN, &adapter->state))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3749
		mod_timer(&adapter->watchdog_timer,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3750
			  round_jiffies(jiffies + 2 * HZ));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3751
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3752
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3753
#define E1000_TX_FLAGS_CSUM		0x00000001
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3754
#define E1000_TX_FLAGS_VLAN		0x00000002
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3755
#define E1000_TX_FLAGS_TSO		0x00000004
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3756
#define E1000_TX_FLAGS_IPV4		0x00000008
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3757
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3758
#define E1000_TX_FLAGS_VLAN_SHIFT	16
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3759
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3760
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
  3761
		     struct sk_buff *skb)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3762
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3763
	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
  3764
	struct e1000_context_desc *context_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3765
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3766
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3767
	u32 cmd_length = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3768
	u16 ipcse = 0, tucse, mss;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3769
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3770
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3771
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3772
	if (!skb_is_gso(skb))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3773
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3774
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3775
	if (skb_header_cloned(skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3776
		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
  3777
		if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3778
			return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3779
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3780
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3781
	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
  3782
	mss = skb_shinfo(skb)->gso_size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3783
	if (skb->protocol == htons(ETH_P_IP)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3784
		struct iphdr *iph = ip_hdr(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3785
		iph->tot_len = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3786
		iph->check = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3787
		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
  3788
		                                         0, IPPROTO_TCP, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3789
		cmd_length = E1000_TXD_CMD_IP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3790
		ipcse = skb_transport_offset(skb) - 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3791
	} else if (skb_is_gso_v6(skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3792
		ipv6_hdr(skb)->payload_len = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3793
		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
  3794
		                                       &ipv6_hdr(skb)->daddr,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3795
		                                       0, IPPROTO_TCP, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3796
		ipcse = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3797
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3798
	ipcss = skb_network_offset(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3799
	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
  3800
	tucss = skb_transport_offset(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3801
	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
  3802
	tucse = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3803
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3804
	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
  3805
	               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
  3806
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3807
	i = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3808
	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
  3809
	buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3810
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3811
	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
  3812
	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
  3813
	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
  3814
	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
  3815
	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
  3816
	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
  3817
	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
  3818
	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
  3819
	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
  3820
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3821
	buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3822
	buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3823
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3824
	i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3825
	if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3826
		i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3827
	tx_ring->next_to_use = i;
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
	return 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3830
}
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
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
  3833
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3834
	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
  3835
	struct e1000_context_desc *context_desc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3836
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3837
	unsigned int i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3838
	u8 css;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3839
	u32 cmd_len = E1000_TXD_CMD_DEXT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3840
	__be16 protocol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3841
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3842
	if (skb->ip_summed != CHECKSUM_PARTIAL)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3843
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3844
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3845
	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
  3846
		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
  3847
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3848
		protocol = skb->protocol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3849
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3850
	switch (protocol) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3851
	case cpu_to_be16(ETH_P_IP):
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3852
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3853
			cmd_len |= E1000_TXD_CMD_TCP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3854
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3855
	case cpu_to_be16(ETH_P_IPV6):
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3856
		/* XXX not handling all IPV6 headers */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3857
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3858
			cmd_len |= E1000_TXD_CMD_TCP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3859
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3860
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3861
		if (unlikely(net_ratelimit()))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3862
			e_warn("checksum_partial proto=%x!\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3863
			       be16_to_cpu(protocol));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3864
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3865
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3866
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3867
	css = skb_transport_offset(skb);
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
	i = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3870
	buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3871
	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
  3872
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3873
	context_desc->lower_setup.ip_config = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3874
	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
  3875
	context_desc->upper_setup.tcp_fields.tucso =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3876
				css + skb->csum_offset;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3877
	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
  3878
	context_desc->tcp_seg_setup.data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3879
	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
  3880
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3881
	buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3882
	buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3883
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3884
	i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3885
	if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3886
		i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3887
	tx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3888
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3889
	return 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3890
}
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
#define E1000_MAX_PER_TXD	8192
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3893
#define E1000_MAX_TXD_PWR	12
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
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
  3896
			struct sk_buff *skb, unsigned int first,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3897
			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
  3898
			unsigned int mss)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3899
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3900
	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
  3901
	struct pci_dev *pdev = adapter->pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3902
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3903
	unsigned int len = skb_headlen(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3904
	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
  3905
	unsigned int f;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3906
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3907
	i = tx_ring->next_to_use;
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
	while (len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3910
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3911
		size = min(len, max_per_txd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3912
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3913
		buffer_info->length = size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3914
		buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3915
		buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3916
		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
  3917
						  size,	PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3918
		buffer_info->mapped_as_page = false;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3919
		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
  3920
			goto dma_error;
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
		len -= size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3923
		offset += size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3924
		count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3925
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3926
		if (len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3927
			i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3928
			if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3929
				i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3930
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3931
	}
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
	for (f = 0; f < nr_frags; f++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3934
		struct skb_frag_struct *frag;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3935
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3936
		frag = &skb_shinfo(skb)->frags[f];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3937
		len = frag->size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3938
		offset = frag->page_offset;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3939
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3940
		while (len) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3941
			i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3942
			if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3943
				i = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3944
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3945
			buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3946
			size = min(len, max_per_txd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3947
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3948
			buffer_info->length = size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3949
			buffer_info->time_stamp = jiffies;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3950
			buffer_info->next_to_watch = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3951
			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
  3952
							offset, size,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3953
							PCI_DMA_TODEVICE);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3954
			buffer_info->mapped_as_page = true;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3955
			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
  3956
				goto dma_error;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3957
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3958
			len -= size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3959
			offset += size;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3960
			count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3961
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3962
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3963
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3964
	tx_ring->buffer_info[i].skb = skb;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3965
	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
  3966
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3967
	return count;
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
dma_error:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3970
	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
  3971
	buffer_info->dma = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3972
	if (count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3973
		count--;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3974
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3975
	while (count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3976
		if (i==0)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3977
			i += tx_ring->count;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3978
		i--;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3979
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3980
		e1000_put_txbuf(adapter, buffer_info);;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3981
	}
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
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3984
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3985
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3986
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
  3987
			   int tx_flags, int count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3988
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3989
	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
  3990
	struct e1000_tx_desc *tx_desc = NULL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3991
	struct e1000_buffer *buffer_info;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3992
	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
  3993
	unsigned int i;
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
	if (tx_flags & E1000_TX_FLAGS_TSO) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3996
		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
  3997
			     E1000_TXD_CMD_TSE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3998
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  3999
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4000
		if (tx_flags & E1000_TX_FLAGS_IPV4)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4001
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4002
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4003
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4004
	if (tx_flags & E1000_TX_FLAGS_CSUM) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4005
		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
  4006
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4007
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4008
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4009
	if (tx_flags & E1000_TX_FLAGS_VLAN) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4010
		txd_lower |= E1000_TXD_CMD_VLE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4011
		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
  4012
	}
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
	i = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4015
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4016
	while (count--) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4017
		buffer_info = &tx_ring->buffer_info[i];
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4018
		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
  4019
		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
  4020
		tx_desc->lower.data =
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4021
			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
  4022
		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
  4023
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4024
		i++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4025
		if (i == tx_ring->count)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4026
			i = 0;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4029
	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
  4030
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4031
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4032
	 * 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
  4033
	 * 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
  4034
	 * applicable for weak-ordered memory model archs,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4035
	 * such as IA-64).
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4036
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4037
	wmb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4038
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4039
	tx_ring->next_to_use = i;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4040
	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
  4041
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4042
	 * 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
  4043
	 * 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
  4044
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4045
	mmiowb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4046
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4047
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4048
#define MINIMUM_DHCP_PACKET_SIZE 282
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4049
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
  4050
				    struct sk_buff *skb)
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
	struct e1000_hw *hw =  &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4053
	u16 length, offset;
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
	if (vlan_tx_tag_present(skb)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4056
		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
  4057
		    (adapter->hw.mng_cookie.status &
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4058
			E1000_MNG_DHCP_COOKIE_STATUS_VLAN)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4059
			return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4060
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4061
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4062
	if (skb->len <= MINIMUM_DHCP_PACKET_SIZE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4063
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4064
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4065
	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
  4066
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4067
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4068
	{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4069
		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
  4070
		struct udphdr *udp;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4071
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4072
		if (ip->protocol != IPPROTO_UDP)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4073
			return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4074
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4075
		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
  4076
		if (ntohs(udp->dest) != 67)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4077
			return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4078
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4079
		offset = (u8 *)udp + 8 - skb->data;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4080
		length = skb->len - offset;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4081
		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
  4082
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4083
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4084
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4085
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4086
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4087
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
  4088
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4089
	struct e1000_adapter *adapter = netdev_priv(netdev);
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
	netif_stop_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4092
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4093
	 * Herbert's original patch had:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4094
	 *  smp_mb__after_netif_stop_queue();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4095
	 * 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
  4096
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4097
	smp_mb();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4098
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4099
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4100
	 * 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
  4101
	 * made room available.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4102
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4103
	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
  4104
		return -EBUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4105
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4106
	/* A reprieve! */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4107
	netif_start_queue(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4108
	++adapter->restart_queue;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4109
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4110
}
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
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
  4113
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4114
	struct e1000_adapter *adapter = netdev_priv(netdev);
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
	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
  4117
		return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4118
	return __e1000_maybe_stop_tx(netdev, size);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4121
#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
  4122
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
  4123
				    struct net_device *netdev)
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
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4126
	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
  4127
	unsigned int first;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4128
	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
  4129
	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
  4130
	unsigned int tx_flags = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4131
	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
  4132
	unsigned int nr_frags;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4133
	unsigned int mss;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4134
	int count = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4135
	int tso;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4136
	unsigned int f;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4137
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4138
	if (test_bit(__E1000_DOWN, &adapter->state)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4139
		dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4140
		return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4141
	}
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 (skb->len <= 0) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4144
		dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4145
		return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4146
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4147
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4148
	mss = skb_shinfo(skb)->gso_size;
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
	 * The controller does a simple calculation to
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4151
	 * 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
  4152
	 * 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
  4153
	 * 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
  4154
	 * 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
  4155
	 * drops.
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
	if (mss) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4158
		u8 hdr_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4159
		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
  4160
		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
  4161
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
		 * 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
  4164
		 * 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
  4165
		 * frags into skb->data
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
		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
  4168
		/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4169
		 * 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
  4170
		 * 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
  4171
		 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4172
		if (skb->data_len && (hdr_len == len)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4173
			unsigned int pull_size;
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
			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
  4176
			if (!__pskb_pull_tail(skb, pull_size)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4177
				e_err("__pskb_pull_tail failed.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4178
				dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4179
				return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4180
			}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4181
			len = skb->len - skb->data_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4182
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4183
	}
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
	/* reserve a descriptor for the offload context */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4186
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4187
		count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4188
	count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4189
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4190
	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
  4191
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4192
	nr_frags = skb_shinfo(skb)->nr_frags;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4193
	for (f = 0; f < nr_frags; f++)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4194
		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
  4195
				       max_txd_pwr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4196
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4197
	if (adapter->hw.mac.tx_pkt_filtering)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4198
		e1000_transfer_dhcp_info(adapter, skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4199
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4200
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4201
	 * 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
  4202
	 * head, otherwise try next time
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
	if (e1000_maybe_stop_tx(netdev, count + 2))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4205
		return NETDEV_TX_BUSY;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4206
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4207
	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
  4208
		tx_flags |= E1000_TX_FLAGS_VLAN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4209
		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
  4210
	}
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
	first = tx_ring->next_to_use;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4213
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4214
	tso = e1000_tso(adapter, skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4215
	if (tso < 0) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4216
		dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4217
		return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4218
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4219
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4220
	if (tso)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4221
		tx_flags |= E1000_TX_FLAGS_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4222
	else if (e1000_tx_csum(adapter, skb))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4223
		tx_flags |= E1000_TX_FLAGS_CSUM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4224
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4225
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4226
	 * 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
  4227
	 * 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
  4228
	 * no longer assume, we must.
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 (skb->protocol == htons(ETH_P_IP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4231
		tx_flags |= E1000_TX_FLAGS_IPV4;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4232
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4233
	/* 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
  4234
	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
  4235
	if (count) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4236
		e1000_tx_queue(adapter, tx_flags, count);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4237
		/* 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
  4238
		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
  4239
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4240
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4241
		dev_kfree_skb_any(skb);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4242
		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
  4243
		tx_ring->next_to_use = first;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4244
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4245
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4246
	return NETDEV_TX_OK;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4247
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4248
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4249
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4250
 * 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
  4251
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4252
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4253
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
  4254
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4255
	struct e1000_adapter *adapter = netdev_priv(netdev);
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
	/* Do the reset outside of interrupt context */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4258
	adapter->tx_timeout_count++;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4259
	schedule_work(&adapter->reset_task);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4262
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
  4263
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4264
	struct e1000_adapter *adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4265
	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
  4266
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4267
	e1000e_reinit_locked(adapter);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4270
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4271
 * e1000_get_stats - Get System Network Statistics
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4272
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4273
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4274
 * 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
  4275
 * 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
  4276
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4277
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
  4278
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4279
	/* only return the current stats */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4280
	return &netdev->stats;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4281
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4282
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4283
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4284
 * 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
  4285
 * @netdev: network interface device structure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4286
 * @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
  4287
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4288
 * Returns 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4289
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4290
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
  4291
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4292
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4293
	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
  4294
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4295
	/* Jumbo frame support */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4296
	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
  4297
	    !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4298
		e_err("Jumbo Frames not supported.\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4299
		return -EINVAL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4300
	}
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
	/* Supported frame sizes */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4303
	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
  4304
	    (max_frame > adapter->max_hw_frame_size)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4305
		e_err("Unsupported MTU setting\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4306
		return -EINVAL;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4307
	}
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
	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
  4310
		msleep(1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4311
	/* 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
  4312
	adapter->max_frame_size = max_frame;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4313
	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
  4314
	netdev->mtu = new_mtu;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4315
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4316
		e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4317
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4318
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4319
	 * 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
  4320
	 * 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
  4321
	 * larger slab size.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4322
	 * i.e. RXBUFFER_2048 --> size-4096 slab
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4323
	 * 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
  4324
	 * fragmented skbs
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4327
	if (max_frame <= 2048)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4328
		adapter->rx_buffer_len = 2048;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4329
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4330
		adapter->rx_buffer_len = 4096;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4331
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4332
	/* 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
  4333
	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
  4334
	     (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
  4335
		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
  4336
					 + ETH_FCS_LEN;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4337
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4338
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4339
		e1000e_up(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4340
	else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4341
		e1000e_reset(adapter);
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
	clear_bit(__E1000_RESETTING, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4344
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4345
	return 0;
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
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
  4349
			   int cmd)
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
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4352
	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
  4353
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4354
	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
  4355
		return -EOPNOTSUPP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4356
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4357
	switch (cmd) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4358
	case SIOCGMIIPHY:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4359
		data->phy_id = adapter->hw.phy.addr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4360
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4361
	case SIOCGMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4362
		e1000_phy_read_status(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4363
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4364
		switch (data->reg_num & 0x1F) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4365
		case MII_BMCR:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4366
			data->val_out = adapter->phy_regs.bmcr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4367
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4368
		case MII_BMSR:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4369
			data->val_out = adapter->phy_regs.bmsr;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4370
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4371
		case MII_PHYSID1:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4372
			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
  4373
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4374
		case MII_PHYSID2:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4375
			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
  4376
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4377
		case MII_ADVERTISE:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4378
			data->val_out = adapter->phy_regs.advertise;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4379
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4380
		case MII_LPA:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4381
			data->val_out = adapter->phy_regs.lpa;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4382
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4383
		case MII_EXPANSION:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4384
			data->val_out = adapter->phy_regs.expansion;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4385
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4386
		case MII_CTRL1000:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4387
			data->val_out = adapter->phy_regs.ctrl1000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4388
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4389
		case MII_STAT1000:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4390
			data->val_out = adapter->phy_regs.stat1000;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4391
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4392
		case MII_ESTATUS:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4393
			data->val_out = adapter->phy_regs.estatus;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4394
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4395
		default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4396
			return -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4397
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4398
		break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4399
	case SIOCSMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4400
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4401
		return -EOPNOTSUPP;
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
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4404
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4405
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4406
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
  4407
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4408
	switch (cmd) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4409
	case SIOCGMIIPHY:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4410
	case SIOCGMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4411
	case SIOCSMIIREG:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4412
		return e1000_mii_ioctl(netdev, ifr, cmd);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4413
	default:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4414
		return -EOPNOTSUPP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4415
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4416
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4417
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4418
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
  4419
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4420
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4421
	u32 i, mac_reg;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4422
	u16 phy_reg;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4423
	int retval = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4424
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4425
	/* copy MAC RARs to PHY RARs */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4426
	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
  4427
		mac_reg = er32(RAL(i));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4428
		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
  4429
		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
  4430
		mac_reg = er32(RAH(i));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4431
		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
  4432
		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
  4433
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4434
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4435
	/* copy MAC MTA to PHY MTA */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4436
	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
  4437
		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
  4438
		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
  4439
		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
  4440
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4441
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4442
	/* configure PHY Rx Control register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4443
	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
  4444
	mac_reg = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4445
	if (mac_reg & E1000_RCTL_UPE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4446
		phy_reg |= BM_RCTL_UPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4447
	if (mac_reg & E1000_RCTL_MPE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4448
		phy_reg |= BM_RCTL_MPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4449
	phy_reg &= ~(BM_RCTL_MO_MASK);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4450
	if (mac_reg & E1000_RCTL_MO_3)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4451
		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
  4452
				<< BM_RCTL_MO_SHIFT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4453
	if (mac_reg & E1000_RCTL_BAM)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4454
		phy_reg |= BM_RCTL_BAM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4455
	if (mac_reg & E1000_RCTL_PMCF)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4456
		phy_reg |= BM_RCTL_PMCF;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4457
	mac_reg = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4458
	if (mac_reg & E1000_CTRL_RFCE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4459
		phy_reg |= BM_RCTL_RFCE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4460
	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
  4461
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4462
	/* enable PHY wakeup in MAC register */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4463
	ew32(WUFC, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4464
	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
  4465
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4466
	/* 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
  4467
	e1e_wphy(&adapter->hw, BM_WUFC, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4468
	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
  4469
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4470
	/* activate PHY wakeup */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4471
	retval = hw->phy.ops.acquire(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4472
	if (retval) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4473
		e_err("Could not acquire PHY\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4474
		return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4475
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4476
	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
  4477
	                         (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4478
	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
  4479
	if (retval) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4480
		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
  4481
		goto out;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4482
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4483
	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
  4484
	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
  4485
	if (retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4486
		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
  4487
out:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4488
	hw->phy.ops.release(hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4489
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4490
	return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4491
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4492
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4493
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
  4494
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4495
	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
  4496
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4497
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4498
	u32 ctrl, ctrl_ext, rctl, status;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4499
	u32 wufc = adapter->wol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4500
	int retval = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4501
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4502
	netif_device_detach(netdev);
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
	if (netif_running(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4505
		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
  4506
		e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4507
		e1000_free_irq(adapter);
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
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4510
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4511
	retval = pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4512
	if (retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4513
		return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4514
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4515
	status = er32(STATUS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4516
	if (status & E1000_STATUS_LU)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4517
		wufc &= ~E1000_WUFC_LNKC;
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
	if (wufc) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4520
		e1000_setup_rctl(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4521
		e1000_set_multi(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4522
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4523
		/* 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
  4524
		if (wufc & E1000_WUFC_MC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4525
			rctl = er32(RCTL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4526
			rctl |= E1000_RCTL_MPE;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4527
			ew32(RCTL, rctl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4528
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4529
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4530
		ctrl = er32(CTRL);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4531
		/* advertise wake from D3Cold */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4532
		#define E1000_CTRL_ADVD3WUC 0x00100000
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4533
		/* phy power management enable */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4534
		#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
  4535
		ctrl |= E1000_CTRL_ADVD3WUC;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4536
		if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4537
			ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4538
		ew32(CTRL, ctrl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4539
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4540
		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
  4541
		    adapter->hw.phy.media_type ==
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4542
		    e1000_media_type_internal_serdes) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4543
			/* keep the laser running in D3 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4544
			ctrl_ext = er32(CTRL_EXT);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4545
			ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4546
			ew32(CTRL_EXT, ctrl_ext);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4547
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4548
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4549
		if (adapter->flags & FLAG_IS_ICH)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4550
			e1000e_disable_gig_wol_ich8lan(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4551
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4552
		/* 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
  4553
		e1000e_disable_pcie_master(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4554
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4555
		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4556
			/* enable wakeup by the PHY */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4557
			retval = e1000_init_phy_wakeup(adapter, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4558
			if (retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4559
				return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4560
		} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4561
			/* enable wakeup by the MAC */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4562
			ew32(WUFC, wufc);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4563
			ew32(WUC, E1000_WUC_PME_EN);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4564
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4565
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4566
		ew32(WUC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4567
		ew32(WUFC, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4568
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4569
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4570
	*enable_wake = !!wufc;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4571
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4572
	/* 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
  4573
	if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4574
	    (hw->mac.ops.check_mng_mode(hw)))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4575
		*enable_wake = true;
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
	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
  4578
		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
  4579
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4580
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4581
	 * 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
  4582
	 * 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
  4583
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4584
	e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4585
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4586
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4587
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4588
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4589
}
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
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
  4592
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4593
	if (sleep && wake) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4594
		pci_prepare_to_sleep(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4595
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4596
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4597
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4598
	pci_wake_from_d3(pdev, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4599
	pci_set_power_state(pdev, PCI_D3hot);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4600
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4601
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4602
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
  4603
                                    bool wake)
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
	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
  4606
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4607
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4608
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4609
	 * 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
  4610
	 * 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
  4611
	 * 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
  4612
	 * downstream port of the pci-e switch.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4613
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4614
	if (adapter->flags & FLAG_IS_QUAD_PORT) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4615
		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
  4616
		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
  4617
		u16 devctl;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4618
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4619
		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
  4620
		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
  4621
		                      (devctl & ~PCI_EXP_DEVCTL_CERE));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4622
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4623
		e1000_power_off(pdev, sleep, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4624
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4625
		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
  4626
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4627
		e1000_power_off(pdev, sleep, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4628
	}
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
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
  4632
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4633
	int pos;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4634
	u16 val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4635
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4636
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4637
	 * 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
  4638
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4639
	 * 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
  4640
	 * 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
  4641
	 * 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
  4642
	 * 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
  4643
	 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4644
	 * 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
  4645
	 * active.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4646
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4647
	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
  4648
	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
  4649
	if (val & 0x2) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4650
		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
  4651
		val &= ~0x2;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4652
		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
  4653
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4654
}
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
#ifdef CONFIG_PM
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4657
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
  4658
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4659
	int retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4660
	bool wake;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4661
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4662
	retval = __e1000_shutdown(pdev, &wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4663
	if (!retval)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4664
		e1000_complete_shutdown(pdev, true, wake);
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
	return retval;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4667
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4668
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4669
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
  4670
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4671
	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
  4672
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4673
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4674
	u32 err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4675
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4676
	pci_set_power_state(pdev, PCI_D0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4677
	pci_restore_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4678
	pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4679
	e1000e_disable_l1aspm(pdev);
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
	err = pci_enable_device_mem(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4682
	if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4683
		dev_err(&pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4684
			"Cannot enable PCI device from suspend\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4685
		return err;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4688
	pci_set_master(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4689
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4690
	pci_enable_wake(pdev, PCI_D3hot, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4691
	pci_enable_wake(pdev, PCI_D3cold, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4692
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4693
	e1000e_set_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4694
	if (netif_running(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4695
		err = e1000_request_irq(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4696
		if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4697
			return err;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4700
	e1000e_power_up_phy(adapter);
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
	/* 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
  4703
	if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4704
		u16 phy_data;
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
		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
  4707
		if (phy_data) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4708
			e_info("PHY Wakeup cause - %s\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4709
				phy_data & E1000_WUS_EX ? "Unicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4710
				phy_data & E1000_WUS_MC ? "Multicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4711
				phy_data & E1000_WUS_BC ? "Broadcast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4712
				phy_data & E1000_WUS_MAG ? "Magic Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4713
				phy_data & E1000_WUS_LNKC ? "Link Status "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4714
				" Change" : "other");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4715
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4716
		e1e_wphy(&adapter->hw, BM_WUS, ~0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4717
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4718
		u32 wus = er32(WUS);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4719
		if (wus) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4720
			e_info("MAC Wakeup cause - %s\n",
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4721
				wus & E1000_WUS_EX ? "Unicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4722
				wus & E1000_WUS_MC ? "Multicast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4723
				wus & E1000_WUS_BC ? "Broadcast Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4724
				wus & E1000_WUS_MAG ? "Magic Packet" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4725
				wus & E1000_WUS_LNKC ? "Link Status Change" :
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4726
				"other");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4727
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4728
		ew32(WUS, ~0);
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
	e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4732
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4733
	e1000_init_manageability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4734
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4735
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4736
		e1000e_up(adapter);
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
	netif_device_attach(netdev);
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
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4741
	 * 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
  4742
	 * 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
  4743
	 * under the control of the driver.
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
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4746
		e1000_get_hw_control(adapter);
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
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4749
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4750
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4751
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4752
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
  4753
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4754
	bool wake = false;
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
	__e1000_shutdown(pdev, &wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4757
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4758
	if (system_state == SYSTEM_POWER_OFF)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4759
		e1000_complete_shutdown(pdev, false, wake);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4760
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4761
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4762
#ifdef CONFIG_NET_POLL_CONTROLLER
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4763
/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4764
 * 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
  4765
 * 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
  4766
 * the interrupt routine is executing.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4767
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4768
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
  4769
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4770
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4771
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4772
	disable_irq(adapter->pdev->irq);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4773
	e1000_intr(adapter->pdev->irq, netdev);
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
	enable_irq(adapter->pdev->irq);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4776
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4777
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4778
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4779
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4780
 * 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
  4781
 * @pdev: Pointer to PCI device
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4782
 * @state: The current pci connection state
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4783
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4784
 * 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
  4785
 * this device has been detected.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4786
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4787
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
  4788
						pci_channel_state_t state)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4789
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4790
	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
  4791
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4792
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4793
	netif_device_detach(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4794
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4795
	if (state == pci_channel_io_perm_failure)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4796
		return PCI_ERS_RESULT_DISCONNECT;
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
	if (netif_running(netdev))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4799
		e1000e_down(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4800
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4801
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4802
	/* Request a slot slot reset. */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4803
	return PCI_ERS_RESULT_NEED_RESET;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4804
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4805
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4806
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4807
 * 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
  4808
 * @pdev: Pointer to PCI device
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
 * 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
  4811
 * 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
  4812
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4813
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
  4814
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4815
	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
  4816
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4817
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4818
	int err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4819
	pci_ers_result_t result;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4820
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4821
	e1000e_disable_l1aspm(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4822
	err = pci_enable_device_mem(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4823
	if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4824
		dev_err(&pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4825
			"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
  4826
		result = PCI_ERS_RESULT_DISCONNECT;
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
		pci_set_master(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4829
		pci_restore_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4830
		pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4831
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4832
		pci_enable_wake(pdev, PCI_D3hot, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4833
		pci_enable_wake(pdev, PCI_D3cold, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4834
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4835
		e1000e_reset(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4836
		ew32(WUS, ~0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4837
		result = PCI_ERS_RESULT_RECOVERED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4838
	}
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
	pci_cleanup_aer_uncorrect_error_status(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4841
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4842
	return result;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4843
}
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4846
 * 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
  4847
 * @pdev: Pointer to PCI device
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4848
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4849
 * 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
  4850
 * 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
  4851
 * second-half of the e1000_resume routine.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4852
 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4853
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
  4854
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4855
	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
  4856
	struct e1000_adapter *adapter = netdev_priv(netdev);
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
	e1000_init_manageability(adapter);
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
	if (netif_running(netdev)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4861
		if (e1000e_up(adapter)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4862
			dev_err(&pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4863
				"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
  4864
			return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4865
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4866
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4867
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4868
	netif_device_attach(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4869
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
	 * 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
  4872
	 * 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
  4873
	 * under the control of the driver.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4874
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4875
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4876
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4877
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4880
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
  4881
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4882
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4883
	struct net_device *netdev = adapter->netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4884
	u32 pba_num;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4885
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4886
	/* print bus type/speed/width info */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4887
	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
  4888
	       /* bus width */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4889
	       ((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
  4890
	        "Width x1"),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4891
	       /* MAC address */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4892
	       netdev->dev_addr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4893
	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
  4894
	       (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
  4895
	e1000e_read_pba_num(hw, &pba_num);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4896
	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
  4897
	       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
  4898
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4899
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4900
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
  4901
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4902
	struct e1000_hw *hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4903
	int ret_val;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4904
	u16 buf = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4905
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4906
	if (hw->mac.type != e1000_82573)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4907
		return;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4908
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4909
	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
  4910
	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
  4911
		/* Deep Smart Power Down (DSPD) */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4912
		dev_warn(&adapter->pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4913
			 "Warning: detected DSPD enabled in EEPROM\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4914
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4915
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4916
	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
  4917
	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
  4918
		/* ASPM enable */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4919
		dev_warn(&adapter->pdev->dev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4920
			 "Warning: detected ASPM enabled in EEPROM\n");
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
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4923
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4924
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
  4925
	.ndo_open		= e1000_open,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4926
	.ndo_stop		= e1000_close,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4927
	.ndo_start_xmit		= e1000_xmit_frame,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4928
	.ndo_get_stats		= e1000_get_stats,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4929
	.ndo_set_multicast_list	= e1000_set_multi,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4930
	.ndo_set_mac_address	= e1000_set_mac,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4931
	.ndo_change_mtu		= e1000_change_mtu,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4932
	.ndo_do_ioctl		= e1000_ioctl,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4933
	.ndo_tx_timeout		= e1000_tx_timeout,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4934
	.ndo_validate_addr	= eth_validate_addr,
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
	.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
  4937
	.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
  4938
	.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
  4939
#ifdef CONFIG_NET_POLL_CONTROLLER
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4940
	.ndo_poll_controller	= e1000_netpoll,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4941
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4942
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4943
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4944
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4945
 * e1000_probe - Device Initialization Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4946
 * @pdev: PCI device information struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4947
 * @ent: entry in e1000_pci_tbl
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4948
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4949
 * Returns 0 on success, negative on failure
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4950
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4951
 * 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
  4952
 * 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
  4953
 * and a hardware reset occur.
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
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
  4956
				 const struct pci_device_id *ent)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4957
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4958
	struct net_device *netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4959
	struct e1000_adapter *adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4960
	struct e1000_hw *hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4961
	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
  4962
	resource_size_t mmio_start, mmio_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4963
	resource_size_t flash_start, flash_len;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4964
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4965
	static int cards_found;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4966
	int i, err, pci_using_dac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4967
	u16 eeprom_data = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4968
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
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
	e1000e_disable_l1aspm(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4971
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4972
	err = pci_enable_device_mem(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4973
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4974
		return err;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4975
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4976
	pci_using_dac = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4977
	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
  4978
	if (!err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4979
		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
  4980
		if (!err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4981
			pci_using_dac = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4982
	} else {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4983
		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
  4984
		if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4985
			err = pci_set_consistent_dma_mask(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4986
							  DMA_BIT_MASK(32));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4987
			if (err) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4988
				dev_err(&pdev->dev, "No usable DMA "
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4989
					"configuration, aborting\n");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4990
				goto err_dma;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4991
			}
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
	err = pci_request_selected_regions_exclusive(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4996
	                                  pci_select_bars(pdev, IORESOURCE_MEM),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4997
	                                  e1000e_driver_name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4998
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  4999
		goto err_pci_reg;
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
	/* AER (Advanced Error Reporting) hooks */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5002
	pci_enable_pcie_error_reporting(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5003
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5004
	pci_set_master(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5005
	/* PCI config space info */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5006
	err = pci_save_state(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5007
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5008
		goto err_alloc_etherdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5009
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5010
	err = -ENOMEM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5011
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5012
	if (!netdev)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5013
		goto err_alloc_etherdev;
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
	SET_NETDEV_DEV(netdev, &pdev->dev);
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
	pci_set_drvdata(pdev, netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5018
	adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5019
	hw = &adapter->hw;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5020
	adapter->netdev = netdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5021
	adapter->pdev = pdev;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5022
	adapter->ei = ei;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5023
	adapter->pba = ei->pba;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5024
	adapter->flags = ei->flags;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5025
	adapter->flags2 = ei->flags2;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5026
	adapter->hw.adapter = adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5027
	adapter->hw.mac.type = ei->mac;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5028
	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
  5029
	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
  5030
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5031
	mmio_start = pci_resource_start(pdev, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5032
	mmio_len = pci_resource_len(pdev, 0);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5033
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5034
	err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5035
	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
  5036
	if (!adapter->hw.hw_addr)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5037
		goto err_ioremap;
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
	if ((adapter->flags & FLAG_HAS_FLASH) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5040
	    (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5041
		flash_start = pci_resource_start(pdev, 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5042
		flash_len = pci_resource_len(pdev, 1);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5043
		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
  5044
		if (!adapter->hw.flash_address)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5045
			goto err_flashmap;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5046
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5047
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5048
	/* construct the net_device struct */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5049
	netdev->netdev_ops		= &e1000e_netdev_ops;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5050
	e1000e_set_ethtool_ops(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5051
	netdev->watchdog_timeo		= 5 * HZ;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5052
	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
  5053
	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
  5054
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5055
	netdev->mem_start = mmio_start;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5056
	netdev->mem_end = mmio_start + mmio_len;
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
	adapter->bd_number = cards_found++;
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
	e1000e_check_options(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5061
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5062
	/* setup adapter struct */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5063
	err = e1000_sw_init(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5064
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5065
		goto err_sw_init;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5066
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5067
	err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5068
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5069
	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
  5070
	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
  5071
	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
  5072
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5073
	err = ei->get_variants(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5074
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5075
		goto err_hw_init;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5076
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5077
	if ((adapter->flags & FLAG_IS_ICH) &&
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5078
	    (adapter->flags & FLAG_READ_ONLY_NVM))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5079
		e1000e_write_protect_nvm_ich8lan(&adapter->hw);
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
	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
  5082
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5083
	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
  5084
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5085
	/* Copper options */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5086
	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
  5087
		adapter->hw.phy.mdix = AUTO_ALL_MODES;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5088
		adapter->hw.phy.disable_polarity_correction = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5089
		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
  5090
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5091
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5092
	if (e1000_check_reset_block(&adapter->hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5093
		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
  5094
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5095
	netdev->features = NETIF_F_SG |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5096
			   NETIF_F_HW_CSUM |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5097
			   NETIF_F_HW_VLAN_TX |
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5098
			   NETIF_F_HW_VLAN_RX;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5099
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5100
	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
  5101
		netdev->features |= NETIF_F_HW_VLAN_FILTER;
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
	netdev->features |= NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5104
	netdev->features |= NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5105
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5106
	netdev->vlan_features |= NETIF_F_TSO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5107
	netdev->vlan_features |= NETIF_F_TSO6;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5108
	netdev->vlan_features |= NETIF_F_HW_CSUM;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5109
	netdev->vlan_features |= NETIF_F_SG;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5110
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5111
	if (pci_using_dac)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5112
		netdev->features |= NETIF_F_HIGHDMA;
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
	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
  5115
		adapter->flags |= FLAG_MNG_PT_ENABLED;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5116
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5117
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5118
	 * 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
  5119
	 * 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
  5120
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5121
	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
  5122
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5123
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5124
	 * 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
  5125
	 * 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
  5126
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5127
	for (i = 0;; i++) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5128
		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
  5129
			break;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5130
		if (i == 2) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5131
			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
  5132
			err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5133
			goto err_eeprom;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5134
		}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5135
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5136
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5137
	e1000_eeprom_checks(adapter);
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
	/* 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
  5140
	if (e1000e_read_mac_addr(&adapter->hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5141
		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
  5142
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5143
	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
  5144
	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
  5145
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5146
	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
  5147
		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
  5148
		err = -EIO;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5149
		goto err_eeprom;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5150
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5151
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5152
	init_timer(&adapter->watchdog_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5153
	adapter->watchdog_timer.function = &e1000_watchdog;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5154
	adapter->watchdog_timer.data = (unsigned long) adapter;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5155
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5156
	init_timer(&adapter->phy_info_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5157
	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
  5158
	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
  5159
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5160
	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
  5161
	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
  5162
	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
  5163
	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
  5164
	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
  5165
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5166
	/* 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
  5167
	adapter->hw.mac.autoneg = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5168
	adapter->fc_autoneg = 1;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5169
	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
  5170
	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
  5171
	adapter->hw.phy.autoneg_advertised = 0x2f;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5172
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5173
	/* ring size defaults */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5174
	adapter->rx_ring->count = 256;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5175
	adapter->tx_ring->count = 256;
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
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5178
	 * 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
  5179
	 * 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
  5180
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5181
	if (adapter->flags & FLAG_APME_IN_WUC) {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5182
		/* 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
  5183
		eeprom_data = er32(WUC);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5184
		eeprom_apme_mask = E1000_WUC_APME;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5185
		if (eeprom_data & E1000_WUC_PHY_WAKE)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5186
			adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5187
	} 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
  5188
		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
  5189
		    (adapter->hw.bus.func == 1))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5190
			e1000_read_nvm(&adapter->hw,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5191
				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
  5192
		else
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5193
			e1000_read_nvm(&adapter->hw,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5194
				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
  5195
	}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5196
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5197
	/* fetch WoL from EEPROM */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5198
	if (eeprom_data & eeprom_apme_mask)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5199
		adapter->eeprom_wol |= E1000_WUFC_MAG;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5200
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5201
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5202
	 * 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
  5203
	 * 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
  5204
	 * wake on lan on a particular port
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5205
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5206
	if (!(adapter->flags & FLAG_HAS_WOL))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5207
		adapter->eeprom_wol = 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5208
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5209
	/* 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
  5210
	adapter->wol = adapter->eeprom_wol;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5211
	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
  5212
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5213
	/* save off EEPROM version number */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5214
	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
  5215
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5216
	/* reset the hardware with the new settings */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5217
	e1000e_reset(adapter);
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
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5220
	 * 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
  5221
	 * 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
  5222
	 * under the control of the driver.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5223
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5224
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5225
		e1000_get_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5226
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5227
	strcpy(netdev->name, "eth%d");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5228
	err = register_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5229
	if (err)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5230
		goto err_register;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5231
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5232
	/* 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
  5233
	netif_carrier_off(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5234
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5235
	e1000_print_device_info(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5236
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5237
	return 0;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5238
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5239
err_register:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5240
	if (!(adapter->flags & FLAG_HAS_AMT))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5241
		e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5242
err_eeprom:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5243
	if (!e1000_check_reset_block(&adapter->hw))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5244
		e1000_phy_hw_reset(&adapter->hw);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5245
err_hw_init:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5246
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5247
	kfree(adapter->tx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5248
	kfree(adapter->rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5249
err_sw_init:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5250
	if (adapter->hw.flash_address)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5251
		iounmap(adapter->hw.flash_address);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5252
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5253
err_flashmap:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5254
	iounmap(adapter->hw.hw_addr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5255
err_ioremap:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5256
	free_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5257
err_alloc_etherdev:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5258
	pci_release_selected_regions(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5259
	                             pci_select_bars(pdev, IORESOURCE_MEM));
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5260
err_pci_reg:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5261
err_dma:
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5262
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5263
	return err;
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5266
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5267
 * e1000_remove - Device Removal Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5268
 * @pdev: PCI device information struct
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5269
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5270
 * 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
  5271
 * 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
  5272
 * 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
  5273
 * memory.
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
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
  5276
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5277
	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
  5278
	struct e1000_adapter *adapter = netdev_priv(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5279
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
	 * 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
  5282
	 * explicitly disable watchdog tasks from being rescheduled
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
	set_bit(__E1000_DOWN, &adapter->state);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5285
	del_timer_sync(&adapter->watchdog_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5286
	del_timer_sync(&adapter->phy_info_timer);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5287
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5288
	cancel_work_sync(&adapter->reset_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5289
	cancel_work_sync(&adapter->watchdog_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5290
	cancel_work_sync(&adapter->downshift_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5291
	cancel_work_sync(&adapter->update_phy_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5292
	cancel_work_sync(&adapter->print_hang_task);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5293
	flush_scheduled_work();
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5294
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5295
	if (!(netdev->flags & IFF_UP))
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5296
		e1000_power_down_phy(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
	unregister_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5299
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5300
	/*
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5301
	 * 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
  5302
	 * 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
  5303
	 */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5304
	e1000_release_hw_control(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5305
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5306
	e1000e_reset_interrupt_capability(adapter);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5307
	kfree(adapter->tx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5308
	kfree(adapter->rx_ring);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5309
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5310
	iounmap(adapter->hw.hw_addr);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5311
	if (adapter->hw.flash_address)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5312
		iounmap(adapter->hw.flash_address);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5313
	pci_release_selected_regions(pdev,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5314
	                             pci_select_bars(pdev, IORESOURCE_MEM));
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
	free_netdev(netdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5317
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5318
	/* AER disable */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5319
	pci_disable_pcie_error_reporting(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5320
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5321
	pci_disable_device(pdev);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5322
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5323
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5324
/* PCI Error Recovery (ERS) */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5325
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
  5326
	.error_detected = e1000_io_error_detected,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5327
	.slot_reset = e1000_io_slot_reset,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5328
	.resume = e1000_io_resume,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5329
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5330
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5331
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
  5332
	{ 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
  5333
	{ 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
  5334
	{ 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
  5335
	{ 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
  5336
	{ 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
  5337
	{ 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
  5338
	{ 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
  5339
	{ 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
  5340
	{ 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
  5341
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5342
	{ 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
  5343
	{ 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
  5344
	{ 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
  5345
	{ 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
  5346
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5347
	{ 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
  5348
	{ 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
  5349
	{ 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
  5350
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5351
	{ 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
  5352
	{ 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
  5353
	{ 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
  5354
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5355
	{ 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
  5356
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5357
	{ 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
  5358
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5359
	{ 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
  5360
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5361
	{ 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
  5362
	  board_80003es2lan },
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5363
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5364
	{ 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
  5365
	{ 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
  5366
	{ 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
  5367
	{ 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
  5368
	{ 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
  5369
	{ 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
  5370
	{ 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
  5371
	{ 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
  5372
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5373
	{ 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
  5374
	{ 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
  5375
	{ 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
  5376
	{ 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
  5377
	{ 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
  5378
	{ 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
  5379
	{ 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
  5380
	{ 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
  5381
	{ 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
  5382
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5383
	{ 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
  5384
	{ 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
  5385
	{ 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
  5386
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5387
	{ 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
  5388
	{ 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
  5389
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5390
	{ 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
  5391
	{ 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
  5392
	{ 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
  5393
	{ 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
  5394
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5395
	{ }	/* terminate list */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5396
};
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5397
MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5398
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5399
/* PCI Device API Driver */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5400
static struct pci_driver e1000_driver = {
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5401
	.name     = e1000e_driver_name,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5402
	.id_table = e1000_pci_tbl,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5403
	.probe    = e1000_probe,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5404
	.remove   = __devexit_p(e1000_remove),
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5405
#ifdef CONFIG_PM
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5406
	/* Power Management Hooks */
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5407
	.suspend  = e1000_suspend,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5408
	.resume   = e1000_resume,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5409
#endif
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5410
	.shutdown = e1000_shutdown,
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5411
	.err_handler = &e1000_err_handler
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
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5415
 * e1000_init_module - Driver Registration Routine
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_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
  5418
 * 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
  5419
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5420
static int __init e1000_init_module(void)
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
	int ret;
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5423
	printk(KERN_INFO "%s: 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
  5424
	       e1000e_driver_name, e1000e_driver_version);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5425
	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
  5426
	       e1000e_driver_name);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5427
	ret = pci_register_driver(&e1000_driver);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5428
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5429
	return ret;
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
module_init(e1000_init_module);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5432
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5433
/**
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5434
 * e1000_exit_module - Driver Exit Cleanup Routine
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5435
 *
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5436
 * 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
  5437
 * from memory.
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5438
 **/
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5439
static void __exit e1000_exit_module(void)
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5440
{
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5441
	pci_unregister_driver(&e1000_driver);
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5442
}
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5443
module_exit(e1000_exit_module);
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
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5446
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
  5447
MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5448
MODULE_LICENSE("GPL");
cedacf485d81 Added e1000e driver for 2.6.33.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  5449
MODULE_VERSION(DRV_VERSION);
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
/* e1000_main.c */