devices/e1000/e1000_main-2.6.29-ethercat.c
author Knud Baastrup <kba@deif.com>
Tue, 14 Apr 2015 13:12:24 -0400
changeset 2629 a2701af27fde
parent 2589 2b9c78543663
permissions -rw-r--r--
Internal SDO requests now synchronized with external requests.
Internal SDO requests are managed by master FSM and can conflict with
external requests managed by slave FSM. The internal SDO requests
includes SDO requests created by an application and external request are
typical created by EtherCAT Tool for SDO upload/download or a directory
fetch initiated with ethercat sdos command. The conflict will cause a
FPWR from an external request to be overwritten by a FPWR from an
internal SDO request (or oppersite) in the same "train" of datagrams.
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     2
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2006 Intel Corporation.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     5
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
     9
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    13
  more details.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    14
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    18
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    21
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    26
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    28
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    29
#include "e1000-2.6.29-ethercat.h"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    30
#include <net/ip6_checksum.h>
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    31
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    32
char e1000_driver_name[] = "ec_e1000";
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    33
static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    34
#define DRV_VERSION "7.3.21-k3-NAPI"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    35
const char e1000_driver_version[] = DRV_VERSION;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    36
static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    37
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    38
/* e1000_pci_tbl - PCI Device ID Table
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    39
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    40
 * Last entry must be all 0s
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    41
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    42
 * Macro expands to...
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    43
 *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    44
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    45
static struct pci_device_id e1000_pci_tbl[] = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    46
	INTEL_E1000_ETHERNET_DEVICE(0x1000),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    47
	INTEL_E1000_ETHERNET_DEVICE(0x1001),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    48
	INTEL_E1000_ETHERNET_DEVICE(0x1004),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    49
	INTEL_E1000_ETHERNET_DEVICE(0x1008),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    50
	INTEL_E1000_ETHERNET_DEVICE(0x1009),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    51
	INTEL_E1000_ETHERNET_DEVICE(0x100C),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    52
	INTEL_E1000_ETHERNET_DEVICE(0x100D),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    53
	INTEL_E1000_ETHERNET_DEVICE(0x100E),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    54
	INTEL_E1000_ETHERNET_DEVICE(0x100F),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    55
	INTEL_E1000_ETHERNET_DEVICE(0x1010),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    56
	INTEL_E1000_ETHERNET_DEVICE(0x1011),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    57
	INTEL_E1000_ETHERNET_DEVICE(0x1012),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    58
	INTEL_E1000_ETHERNET_DEVICE(0x1013),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    59
	INTEL_E1000_ETHERNET_DEVICE(0x1014),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    60
	INTEL_E1000_ETHERNET_DEVICE(0x1015),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    61
	INTEL_E1000_ETHERNET_DEVICE(0x1016),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    62
	INTEL_E1000_ETHERNET_DEVICE(0x1017),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    63
	INTEL_E1000_ETHERNET_DEVICE(0x1018),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    64
	INTEL_E1000_ETHERNET_DEVICE(0x1019),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    65
	INTEL_E1000_ETHERNET_DEVICE(0x101A),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    66
	INTEL_E1000_ETHERNET_DEVICE(0x101D),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    67
	INTEL_E1000_ETHERNET_DEVICE(0x101E),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    68
	INTEL_E1000_ETHERNET_DEVICE(0x1026),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    69
	INTEL_E1000_ETHERNET_DEVICE(0x1027),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    70
	INTEL_E1000_ETHERNET_DEVICE(0x1028),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    71
	INTEL_E1000_ETHERNET_DEVICE(0x1075),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    72
	INTEL_E1000_ETHERNET_DEVICE(0x1076),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    73
	INTEL_E1000_ETHERNET_DEVICE(0x1077),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    74
	INTEL_E1000_ETHERNET_DEVICE(0x1078),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    75
	INTEL_E1000_ETHERNET_DEVICE(0x1079),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    76
	INTEL_E1000_ETHERNET_DEVICE(0x107A),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    77
	INTEL_E1000_ETHERNET_DEVICE(0x107B),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    78
	INTEL_E1000_ETHERNET_DEVICE(0x107C),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    79
	INTEL_E1000_ETHERNET_DEVICE(0x108A),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    80
	INTEL_E1000_ETHERNET_DEVICE(0x1099),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    81
	INTEL_E1000_ETHERNET_DEVICE(0x10B5),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    82
	/* required last entry */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    83
	{0,}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    84
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    85
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    86
// do not auto-load driver
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    87
// MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    88
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    89
int e1000_up(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    90
void e1000_down(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    91
void e1000_reinit_locked(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    92
void e1000_reset(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    93
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    94
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    95
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    96
void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    97
void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    98
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
    99
                             struct e1000_tx_ring *txdr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   100
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   101
                             struct e1000_rx_ring *rxdr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   102
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   103
                             struct e1000_tx_ring *tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   104
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   105
                             struct e1000_rx_ring *rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   106
void e1000_update_stats(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   107
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   108
static int e1000_init_module(void);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   109
static void e1000_exit_module(void);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   110
static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   111
static void __devexit e1000_remove(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   112
static int e1000_alloc_queues(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   113
static int e1000_sw_init(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   114
static int e1000_open(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   115
static int e1000_close(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   116
static void e1000_configure_tx(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   117
static void e1000_configure_rx(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   118
static void e1000_setup_rctl(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   119
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   120
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   121
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   122
                                struct e1000_tx_ring *tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   123
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   124
                                struct e1000_rx_ring *rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   125
static void e1000_set_rx_mode(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   126
static void e1000_update_phy_info(unsigned long data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   127
static void e1000_watchdog(unsigned long data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   128
static void e1000_82547_tx_fifo_stall(unsigned long data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   129
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   130
static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   131
static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   132
static int e1000_set_mac(struct net_device *netdev, void *p);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   133
void ec_poll(struct net_device *);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   134
static irqreturn_t e1000_intr(int irq, void *data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   135
static irqreturn_t e1000_intr_msi(int irq, void *data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   136
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   137
			       struct e1000_tx_ring *tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   138
static int e1000_clean(struct napi_struct *napi, int budget);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   139
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   140
			       struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   141
			       int *work_done, int work_to_do);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   142
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   143
                                   struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   144
				   int cleaned_count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   145
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   146
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   147
			   int cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   148
static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   149
static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   150
static void e1000_tx_timeout(struct net_device *dev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   151
static void e1000_reset_task(struct work_struct *work);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   152
static void e1000_smartspeed(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   153
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   154
                                       struct sk_buff *skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   155
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   156
static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   157
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   158
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   159
static void e1000_restore_vlan(struct e1000_adapter *adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   160
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   161
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   162
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   163
static int e1000_resume(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   164
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   165
static void e1000_shutdown(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   166
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   167
#ifdef CONFIG_NET_POLL_CONTROLLER
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   168
/* for netdump / net console */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   169
static void e1000_netpoll (struct net_device *netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   170
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   171
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   172
#define COPYBREAK_DEFAULT 256
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   173
static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   174
module_param(copybreak, uint, 0644);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   175
MODULE_PARM_DESC(copybreak,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   176
	"Maximum size of packet that is copied to a new buffer on receive");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   177
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   178
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   179
                     pci_channel_state_t state);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   180
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   181
static void e1000_io_resume(struct pci_dev *pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   182
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   183
static struct pci_error_handlers e1000_err_handler = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   184
	.error_detected = e1000_io_error_detected,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   185
	.slot_reset = e1000_io_slot_reset,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   186
	.resume = e1000_io_resume,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   187
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   188
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   189
static struct pci_driver e1000_driver = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   190
	.name     = e1000_driver_name,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   191
	.id_table = e1000_pci_tbl,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   192
	.probe    = e1000_probe,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   193
	.remove   = __devexit_p(e1000_remove),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   194
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   195
	/* Power Managment Hooks */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   196
	.suspend  = e1000_suspend,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   197
	.resume   = e1000_resume,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   198
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   199
	.shutdown = e1000_shutdown,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   200
	.err_handler = &e1000_err_handler
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   201
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   202
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   203
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   204
MODULE_DESCRIPTION("EtherCAT-capable Intel(R) PRO/1000 Network Driver");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   205
MODULE_LICENSE("GPL");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   206
MODULE_VERSION(DRV_VERSION);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   207
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   208
static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   209
module_param(debug, int, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   210
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   211
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   212
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   213
 * e1000_init_module - Driver Registration Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   214
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   215
 * e1000_init_module is the first routine called when the driver is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   216
 * loaded. All it does is register with the PCI subsystem.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   217
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   218
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   219
static int __init e1000_init_module(void)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   220
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   221
	int ret;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   222
	printk(KERN_INFO "%s - version %s\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   223
	       e1000_driver_string, e1000_driver_version);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   224
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   225
	printk(KERN_INFO "%s\n", e1000_copyright);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   226
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   227
	ret = pci_register_driver(&e1000_driver);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   228
	if (copybreak != COPYBREAK_DEFAULT) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   229
		if (copybreak == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   230
			printk(KERN_INFO "e1000: copybreak disabled\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   231
		else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   232
			printk(KERN_INFO "e1000: copybreak enabled for "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   233
			       "packets <= %u bytes\n", copybreak);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   234
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   235
	return ret;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   236
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   237
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   238
module_init(e1000_init_module);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   239
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   240
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   241
 * e1000_exit_module - Driver Exit Cleanup Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   242
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   243
 * e1000_exit_module is called just before the driver is removed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   244
 * from memory.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   245
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   246
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   247
static void __exit e1000_exit_module(void)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   248
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   249
	pci_unregister_driver(&e1000_driver);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   250
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   251
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   252
module_exit(e1000_exit_module);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   253
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   254
static int e1000_request_irq(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   255
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   256
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   257
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   258
	irq_handler_t handler = e1000_intr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   259
	int irq_flags = IRQF_SHARED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   260
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   261
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   262
 	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   263
 		return 0;
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
   264
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   265
	if (hw->mac_type >= e1000_82571) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   266
		adapter->have_msi = !pci_enable_msi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   267
		if (adapter->have_msi) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   268
			handler = e1000_intr_msi;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   269
			irq_flags = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   270
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   271
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   272
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   273
	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   274
	                  netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   275
	if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   276
		if (adapter->have_msi)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   277
			pci_disable_msi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   278
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   279
		        "Unable to allocate interrupt Error: %d\n", err);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   280
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   281
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   282
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   283
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   284
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   285
static void e1000_free_irq(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   286
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   287
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   288
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   289
	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   290
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   291
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   292
	free_irq(adapter->pdev->irq, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   293
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   294
	if (adapter->have_msi)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   295
		pci_disable_msi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   296
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   297
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   298
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   299
 * e1000_irq_disable - Mask off interrupt generation on the NIC
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   300
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   301
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   302
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   303
static void e1000_irq_disable(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   304
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   305
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   306
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   307
	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   308
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   309
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   310
	ew32(IMC, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   311
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   312
	synchronize_irq(adapter->pdev->irq);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   313
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   314
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   315
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   316
 * e1000_irq_enable - Enable default interrupt generation settings
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   317
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   318
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   319
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   320
static void e1000_irq_enable(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   321
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   322
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   323
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   324
	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   325
		return;
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
   326
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   327
	ew32(IMS, IMS_ENABLE_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   328
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   329
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   330
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   331
static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   332
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   333
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   334
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   335
	u16 vid = hw->mng_cookie.vlan_id;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   336
	u16 old_vid = adapter->mng_vlan_id;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   337
	if (adapter->vlgrp) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   338
		if (!vlan_group_get_device(adapter->vlgrp, vid)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   339
			if (hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   340
				E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   341
				e1000_vlan_rx_add_vid(netdev, vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   342
				adapter->mng_vlan_id = vid;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   343
			} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   344
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   345
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   346
			if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   347
					(vid != old_vid) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   348
			    !vlan_group_get_device(adapter->vlgrp, old_vid))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   349
				e1000_vlan_rx_kill_vid(netdev, old_vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   350
		} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   351
			adapter->mng_vlan_id = vid;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   352
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   353
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   354
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   355
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   356
 * e1000_release_hw_control - release control of the h/w to f/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   357
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   358
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   359
 * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   360
 * For ASF and Pass Through versions of f/w this means that the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   361
 * driver is no longer loaded. For AMT version (only with 82573) i
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   362
 * of the f/w this means that the network i/f is closed.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   363
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   364
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   365
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   366
static void e1000_release_hw_control(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   367
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   368
	u32 ctrl_ext;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   369
	u32 swsm;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   370
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   371
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   372
	/* Let firmware taken over control of h/w */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   373
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   374
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   375
		swsm = er32(SWSM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   376
		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   377
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   378
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   379
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   380
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   381
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   382
		ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   383
		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   384
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   385
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   386
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   387
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   388
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   389
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   390
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   391
 * e1000_get_hw_control - get control of the h/w from f/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   392
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   393
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   394
 * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   395
 * For ASF and Pass Through versions of f/w this means that
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   396
 * the driver is loaded. For AMT version (only with 82573)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   397
 * of the f/w this means that the network i/f is open.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   398
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   399
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   400
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   401
static void e1000_get_hw_control(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   402
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   403
	u32 ctrl_ext;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   404
	u32 swsm;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   405
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   406
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   407
	/* Let firmware know the driver has taken over */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   408
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   409
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   410
		swsm = er32(SWSM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   411
		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   412
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   413
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   414
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   415
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   416
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   417
		ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   418
		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   419
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   420
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   421
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   422
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   423
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   424
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   425
static void e1000_init_manageability(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   426
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   427
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   428
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   429
	if (adapter->en_mng_pt) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   430
		u32 manc = er32(MANC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   431
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   432
		/* disable hardware interception of ARP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   433
		manc &= ~(E1000_MANC_ARP_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   434
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   435
		/* enable receiving management packets to the host */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   436
		/* this will probably generate destination unreachable messages
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   437
		 * from the host OS, but the packets will be handled on SMBUS */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   438
		if (hw->has_manc2h) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   439
			u32 manc2h = er32(MANC2H);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   440
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   441
			manc |= E1000_MANC_EN_MNG2HOST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   442
#define E1000_MNG2HOST_PORT_623 (1 << 5)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   443
#define E1000_MNG2HOST_PORT_664 (1 << 6)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   444
			manc2h |= E1000_MNG2HOST_PORT_623;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   445
			manc2h |= E1000_MNG2HOST_PORT_664;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   446
			ew32(MANC2H, manc2h);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   447
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   448
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   449
		ew32(MANC, manc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   450
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   451
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   452
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   453
static void e1000_release_manageability(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   454
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   455
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   456
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   457
	if (adapter->en_mng_pt) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   458
		u32 manc = er32(MANC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   459
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   460
		/* re-enable hardware interception of ARP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   461
		manc |= E1000_MANC_ARP_EN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   462
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   463
		if (hw->has_manc2h)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   464
			manc &= ~E1000_MANC_EN_MNG2HOST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   465
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   466
		/* don't explicitly have to mess with MANC2H since
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   467
		 * MANC has an enable disable that gates MANC2H */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   468
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   469
		ew32(MANC, manc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   470
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   471
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   472
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   473
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   474
 * e1000_configure - configure the hardware for RX and TX
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   475
 * @adapter = private board structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   476
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   477
static void e1000_configure(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   478
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   479
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   480
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   481
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   482
	e1000_set_rx_mode(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   483
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   484
	e1000_restore_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   485
	e1000_init_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   486
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   487
	e1000_configure_tx(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   488
	e1000_setup_rctl(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   489
	e1000_configure_rx(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   490
	/* call E1000_DESC_UNUSED which always leaves
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   491
	 * at least 1 descriptor unused to make sure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   492
	 * next_to_use != next_to_clean */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   493
	for (i = 0; i < adapter->num_rx_queues; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   494
		struct e1000_rx_ring *ring = &adapter->rx_ring[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   495
		if (adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   496
			/* fill rx ring completely! */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   497
			adapter->alloc_rx_buf(adapter, ring, ring->count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   498
		} else {
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
   499
			/* this one leaves the last ring element unallocated! */
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   500
			adapter->alloc_rx_buf(adapter, ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   501
					E1000_DESC_UNUSED(ring));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   502
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   503
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   504
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   505
	adapter->tx_queue_len = netdev->tx_queue_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   506
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   507
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   508
int e1000_up(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   509
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   510
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   511
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   512
	/* hardware has been reset, we need to reload some things */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   513
	e1000_configure(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   514
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   515
	clear_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   516
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   517
	if (!adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   518
		napi_enable(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   519
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   520
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   521
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   522
		/* fire a link change interrupt to start the watchdog */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   523
		ew32(ICS, E1000_ICS_LSC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   524
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   525
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   526
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   527
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   528
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   529
 * e1000_power_up_phy - restore link in case the phy was powered down
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   530
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   531
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   532
 * The phy may be powered down to save power and turn off link when the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   533
 * driver is unloaded and wake on lan is not enabled (among others)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   534
 * *** this routine MUST be followed by a call to e1000_reset ***
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   535
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   536
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   537
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   538
void e1000_power_up_phy(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   539
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   540
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   541
	u16 mii_reg = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   542
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   543
	/* Just clear the power down bit to wake the phy back up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   544
	if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   545
		/* according to the manual, the phy will retain its
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   546
		 * settings across a power-down/up cycle */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   547
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   548
		mii_reg &= ~MII_CR_POWER_DOWN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   549
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   550
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   551
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   552
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   553
static void e1000_power_down_phy(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   554
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   555
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   556
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   557
	/* Power down the PHY so no link is implied when interface is down *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   558
	 * The PHY cannot be powered down if any of the following is true *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   559
	 * (a) WoL is enabled
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   560
	 * (b) AMT is active
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   561
	 * (c) SoL/IDER session is active */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   562
	if (!adapter->wol && hw->mac_type >= e1000_82540 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   563
	   hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   564
		u16 mii_reg = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   565
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   566
		switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   567
		case e1000_82540:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   568
		case e1000_82545:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   569
		case e1000_82545_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   570
		case e1000_82546:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   571
		case e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   572
		case e1000_82541:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   573
		case e1000_82541_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   574
		case e1000_82547:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   575
		case e1000_82547_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   576
			if (er32(MANC) & E1000_MANC_SMBUS_EN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   577
				goto out;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   578
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   579
		case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   580
		case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   581
		case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   582
		case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   583
		case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   584
			if (e1000_check_mng_mode(hw) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   585
			    e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   586
				goto out;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   587
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   588
		default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   589
			goto out;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   590
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   591
		e1000_read_phy_reg(hw, PHY_CTRL, &mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   592
		mii_reg |= MII_CR_POWER_DOWN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   593
		e1000_write_phy_reg(hw, PHY_CTRL, mii_reg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   594
		mdelay(1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   595
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   596
out:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   597
	return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   598
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   599
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   600
void e1000_down(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   601
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   602
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   603
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   604
	/* signal that we're down so the interrupt handler does not
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   605
	 * reschedule our watchdog timer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   606
	set_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   607
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   608
	if (!adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   609
		napi_disable(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   610
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   611
		e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   612
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   613
		del_timer_sync(&adapter->tx_fifo_stall_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   614
		del_timer_sync(&adapter->watchdog_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   615
		del_timer_sync(&adapter->phy_info_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   616
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   617
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   618
	netdev->tx_queue_len = adapter->tx_queue_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   619
	adapter->link_speed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   620
	adapter->link_duplex = 0;
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
   621
	if (!adapter->ecdev) {
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   622
		netif_carrier_off(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   623
		netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   624
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   625
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   626
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   627
	e1000_clean_all_tx_rings(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   628
	e1000_clean_all_rx_rings(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   629
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   630
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   631
void e1000_reinit_locked(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   632
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   633
	WARN_ON(in_interrupt());
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   634
	while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   635
		msleep(1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   636
	e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   637
	e1000_up(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   638
	clear_bit(__E1000_RESETTING, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   639
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   640
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   641
void e1000_reset(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   642
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   643
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   644
	u32 pba = 0, tx_space, min_tx_space, min_rx_space;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   645
	u16 fc_high_water_mark = E1000_FC_HIGH_DIFF;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   646
	bool legacy_pba_adjust = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   647
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   648
	/* Repartition Pba for greater than 9k mtu
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   649
	 * To take effect CTRL.RST is required.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   650
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   651
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   652
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   653
	case e1000_82542_rev2_0:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   654
	case e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   655
	case e1000_82543:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   656
	case e1000_82544:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   657
	case e1000_82540:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   658
	case e1000_82541:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   659
	case e1000_82541_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   660
		legacy_pba_adjust = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   661
		pba = E1000_PBA_48K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   662
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   663
	case e1000_82545:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   664
	case e1000_82545_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   665
	case e1000_82546:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   666
	case e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   667
		pba = E1000_PBA_48K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   668
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   669
	case e1000_82547:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   670
	case e1000_82547_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   671
		legacy_pba_adjust = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   672
		pba = E1000_PBA_30K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   673
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   674
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   675
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   676
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   677
		pba = E1000_PBA_38K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   678
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   679
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   680
		pba = E1000_PBA_20K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   681
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   682
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   683
		pba = E1000_PBA_8K;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   684
	case e1000_undefined:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   685
	case e1000_num_macs:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   686
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   687
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   688
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   689
	if (legacy_pba_adjust) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   690
		if (adapter->netdev->mtu > E1000_RXBUFFER_8192)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   691
			pba -= 8; /* allocate more FIFO for Tx */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   692
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   693
		if (hw->mac_type == e1000_82547) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   694
			adapter->tx_fifo_head = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   695
			adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   696
			adapter->tx_fifo_size =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   697
				(E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   698
			atomic_set(&adapter->tx_fifo_stall, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   699
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   700
	} else if (hw->max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   701
		/* adjust PBA for jumbo frames */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   702
		ew32(PBA, pba);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   703
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   704
		/* To maintain wire speed transmits, the Tx FIFO should be
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   705
		 * large enough to accomodate two full transmit packets,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   706
		 * rounded up to the next 1KB and expressed in KB.  Likewise,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   707
		 * the Rx FIFO should be large enough to accomodate at least
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   708
		 * one full receive packet and is similarly rounded up and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   709
		 * expressed in KB. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   710
		pba = er32(PBA);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   711
		/* upper 16 bits has Tx packet buffer allocation size in KB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   712
		tx_space = pba >> 16;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   713
		/* lower 16 bits has Rx packet buffer allocation size in KB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   714
		pba &= 0xffff;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   715
		/* don't include ethernet FCS because hardware appends/strips */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   716
		min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   717
		               VLAN_TAG_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   718
		min_tx_space = min_rx_space;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   719
		min_tx_space *= 2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   720
		min_tx_space = ALIGN(min_tx_space, 1024);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   721
		min_tx_space >>= 10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   722
		min_rx_space = ALIGN(min_rx_space, 1024);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   723
		min_rx_space >>= 10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   724
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   725
		/* If current Tx allocation is less than the min Tx FIFO size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   726
		 * and the min Tx FIFO size is less than the current Rx FIFO
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   727
		 * allocation, take space away from current Rx allocation */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   728
		if (tx_space < min_tx_space &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   729
		    ((min_tx_space - tx_space) < pba)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   730
			pba = pba - (min_tx_space - tx_space);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   731
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   732
			/* PCI/PCIx hardware has PBA alignment constraints */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   733
			switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   734
			case e1000_82545 ... e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   735
				pba &= ~(E1000_PBA_8K - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   736
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   737
			default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   738
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   739
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   740
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   741
			/* if short on rx space, rx wins and must trump tx
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   742
			 * adjustment or use Early Receive if available */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   743
			if (pba < min_rx_space) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   744
				switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   745
				case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   746
					/* ERT enabled in e1000_configure_rx */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   747
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   748
				default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   749
					pba = min_rx_space;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   750
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   751
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   752
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   753
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   754
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   755
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   756
	ew32(PBA, pba);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   757
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   758
	/* flow control settings */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   759
	/* Set the FC high water mark to 90% of the FIFO size.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   760
	 * Required to clear last 3 LSB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   761
	fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   762
	/* We can't use 90% on small FIFOs because the remainder
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   763
	 * would be less than 1 full frame.  In this case, we size
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   764
	 * it to allow at least a full frame above the high water
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   765
	 *  mark. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   766
	if (pba < E1000_PBA_16K)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   767
		fc_high_water_mark = (pba * 1024) - 1600;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   768
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   769
	hw->fc_high_water = fc_high_water_mark;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   770
	hw->fc_low_water = fc_high_water_mark - 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   771
	if (hw->mac_type == e1000_80003es2lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   772
		hw->fc_pause_time = 0xFFFF;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   773
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   774
		hw->fc_pause_time = E1000_FC_PAUSE_TIME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   775
	hw->fc_send_xon = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   776
	hw->fc = hw->original_fc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   777
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   778
	/* Allow time for pending master requests to run */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   779
	e1000_reset_hw(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   780
	if (hw->mac_type >= e1000_82544)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   781
		ew32(WUC, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   782
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   783
	if (e1000_init_hw(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   784
		DPRINTK(PROBE, ERR, "Hardware Error\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   785
	e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   786
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   787
	/* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   788
	if (hw->mac_type >= e1000_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   789
	    hw->mac_type <= e1000_82547_rev_2 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   790
	    hw->autoneg == 1 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   791
	    hw->autoneg_advertised == ADVERTISE_1000_FULL) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   792
		u32 ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   793
		/* clear phy power management bit if we are in gig only mode,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   794
		 * which if enabled will attempt negotiation to 100Mb, which
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   795
		 * can cause a loss of link at power off or driver unload */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   796
		ctrl &= ~E1000_CTRL_SWDPIN3;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   797
		ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   798
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   799
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   800
	/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   801
	ew32(VET, ETHERNET_IEEE_VLAN_TYPE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   802
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   803
	e1000_reset_adaptive(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   804
	e1000_phy_get_info(hw, &adapter->phy_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   805
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   806
	if (!adapter->smart_power_down &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   807
	    (hw->mac_type == e1000_82571 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   808
	     hw->mac_type == e1000_82572)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   809
		u16 phy_data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   810
		/* speed up time to link by disabling smart power down, ignore
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   811
		 * the return value of this function because there is nothing
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   812
		 * different we would do if it failed */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   813
		e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   814
		                   &phy_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   815
		phy_data &= ~IGP02E1000_PM_SPD;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   816
		e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   817
		                    phy_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   818
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   819
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   820
	e1000_release_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   821
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   822
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   823
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   824
 *  Dump the eeprom for users having checksum issues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   825
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   826
static void e1000_dump_eeprom(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   827
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   828
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   829
	struct ethtool_eeprom eeprom;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   830
	const struct ethtool_ops *ops = netdev->ethtool_ops;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   831
	u8 *data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   832
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   833
	u16 csum_old, csum_new = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   834
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   835
	eeprom.len = ops->get_eeprom_len(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   836
	eeprom.offset = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   837
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   838
	data = kmalloc(eeprom.len, GFP_KERNEL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   839
	if (!data) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   840
		printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   841
		       " data\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   842
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   843
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   844
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   845
	ops->get_eeprom(netdev, &eeprom, data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   846
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   847
	csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   848
		   (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   849
	for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   850
		csum_new += data[i] + (data[i + 1] << 8);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   851
	csum_new = EEPROM_SUM - csum_new;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   852
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   853
	printk(KERN_ERR "/*********************/\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   854
	printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   855
	printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   856
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   857
	printk(KERN_ERR "Offset    Values\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   858
	printk(KERN_ERR "========  ======\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   859
	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   860
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   861
	printk(KERN_ERR "Include this output when contacting your support "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   862
	       "provider.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   863
	printk(KERN_ERR "This is not a software error! Something bad "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   864
	       "happened to your hardware or\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   865
	printk(KERN_ERR "EEPROM image. Ignoring this "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   866
	       "problem could result in further problems,\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   867
	printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   868
	printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   869
	       "which is invalid\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   870
	printk(KERN_ERR "and requires you to set the proper MAC "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   871
	       "address manually before continuing\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   872
	printk(KERN_ERR "to enable this network device.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   873
	printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   874
	       "to your hardware vendor\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   875
	printk(KERN_ERR "or Intel Customer Support.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   876
	printk(KERN_ERR "/*********************/\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   877
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   878
	kfree(data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   879
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   880
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   881
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   882
 * e1000_is_need_ioport - determine if an adapter needs ioport resources or not
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   883
 * @pdev: PCI device information struct
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   884
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   885
 * Return true if an adapter needs ioport resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   886
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   887
static int e1000_is_need_ioport(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   888
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   889
	switch (pdev->device) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   890
	case E1000_DEV_ID_82540EM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   891
	case E1000_DEV_ID_82540EM_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   892
	case E1000_DEV_ID_82540EP:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   893
	case E1000_DEV_ID_82540EP_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   894
	case E1000_DEV_ID_82540EP_LP:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   895
	case E1000_DEV_ID_82541EI:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   896
	case E1000_DEV_ID_82541EI_MOBILE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   897
	case E1000_DEV_ID_82541ER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   898
	case E1000_DEV_ID_82541ER_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   899
	case E1000_DEV_ID_82541GI:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   900
	case E1000_DEV_ID_82541GI_LF:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   901
	case E1000_DEV_ID_82541GI_MOBILE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   902
	case E1000_DEV_ID_82544EI_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   903
	case E1000_DEV_ID_82544EI_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   904
	case E1000_DEV_ID_82544GC_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   905
	case E1000_DEV_ID_82544GC_LOM:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   906
	case E1000_DEV_ID_82545EM_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   907
	case E1000_DEV_ID_82545EM_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   908
	case E1000_DEV_ID_82546EB_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   909
	case E1000_DEV_ID_82546EB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   910
	case E1000_DEV_ID_82546EB_QUAD_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   911
		return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   912
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   913
		return false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   914
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   915
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   916
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   917
static const struct net_device_ops e1000_netdev_ops = {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   918
	.ndo_open		= e1000_open,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   919
	.ndo_stop		= e1000_close,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   920
	.ndo_start_xmit		= e1000_xmit_frame,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   921
	.ndo_get_stats		= e1000_get_stats,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   922
	.ndo_set_rx_mode	= e1000_set_rx_mode,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   923
	.ndo_set_mac_address	= e1000_set_mac,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   924
	.ndo_tx_timeout 	= e1000_tx_timeout,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   925
	.ndo_change_mtu		= e1000_change_mtu,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   926
	.ndo_do_ioctl		= e1000_ioctl,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   927
	.ndo_validate_addr	= eth_validate_addr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   928
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   929
	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   930
	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   931
	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   932
#ifdef CONFIG_NET_POLL_CONTROLLER
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   933
	.ndo_poll_controller	= e1000_netpoll,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   934
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   935
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   936
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   937
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   938
 * e1000_probe - Device Initialization Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   939
 * @pdev: PCI device information struct
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   940
 * @ent: entry in e1000_pci_tbl
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   941
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   942
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   943
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   944
 * e1000_probe initializes an adapter identified by a pci_dev structure.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   945
 * The OS initialization, configuring of the adapter private structure,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   946
 * and a hardware reset occur.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   947
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   948
static int __devinit e1000_probe(struct pci_dev *pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   949
				 const struct pci_device_id *ent)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   950
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   951
	struct net_device *netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   952
	struct e1000_adapter *adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   953
	struct e1000_hw *hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   954
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   955
	static int cards_found = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   956
	static int global_quad_port_a = 0; /* global ksp3 port a indication */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   957
	int i, err, pci_using_dac;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   958
	u16 eeprom_data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   959
	u16 eeprom_apme_mask = E1000_EEPROM_APME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   960
	int bars, need_ioport;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   961
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   962
	/* do not allocate ioport bars when not needed */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   963
	need_ioport = e1000_is_need_ioport(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   964
	if (need_ioport) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   965
		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   966
		err = pci_enable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   967
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   968
		bars = pci_select_bars(pdev, IORESOURCE_MEM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   969
		err = pci_enable_device_mem(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   970
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   971
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   972
		return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   973
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   974
	if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   975
	    !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   976
		pci_using_dac = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   977
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   978
		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   979
		if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   980
			err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   981
			if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   982
				E1000_ERR("No usable DMA configuration, "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   983
					  "aborting\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   984
				goto err_dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   985
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   986
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   987
		pci_using_dac = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   988
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   989
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   990
	err = pci_request_selected_regions(pdev, bars, e1000_driver_name);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   991
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   992
		goto err_pci_reg;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   993
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   994
	pci_set_master(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   995
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   996
	err = -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   997
	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   998
	if (!netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
   999
		goto err_alloc_etherdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1001
	SET_NETDEV_DEV(netdev, &pdev->dev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1002
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1003
	pci_set_drvdata(pdev, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1004
	adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1005
	adapter->netdev = netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1006
	adapter->pdev = pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1007
	adapter->msg_enable = (1 << debug) - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1008
	adapter->bars = bars;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1009
	adapter->need_ioport = need_ioport;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1010
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1011
	hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1012
	hw->back = adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1013
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1014
	err = -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1015
	hw->hw_addr = pci_ioremap_bar(pdev, BAR_0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1016
	if (!hw->hw_addr)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1017
		goto err_ioremap;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1018
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1019
	if (adapter->need_ioport) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1020
		for (i = BAR_1; i <= BAR_5; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1021
			if (pci_resource_len(pdev, i) == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1022
				continue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1023
			if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1024
				hw->io_base = pci_resource_start(pdev, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1025
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1026
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1027
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1028
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1029
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1030
	netdev->netdev_ops = &e1000_netdev_ops;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1031
	e1000_set_ethtool_ops(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1032
	netdev->watchdog_timeo = 5 * HZ;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1033
	netif_napi_add(netdev, &adapter->napi, e1000_clean, 64);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1034
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1035
	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1036
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1037
	adapter->bd_number = cards_found;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1038
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1039
	/* setup the private structure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1040
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1041
	err = e1000_sw_init(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1042
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1043
		goto err_sw_init;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1044
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1045
	err = -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1046
	/* Flash BAR mapping must happen after e1000_sw_init
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1047
	 * because it depends on mac_type */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1048
	if ((hw->mac_type == e1000_ich8lan) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1049
	   (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1050
		hw->flash_address = pci_ioremap_bar(pdev, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1051
		if (!hw->flash_address)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1052
			goto err_flashmap;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1053
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1054
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1055
	if (e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1056
		DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1057
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1058
	if (hw->mac_type >= e1000_82543) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1059
		netdev->features = NETIF_F_SG |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1060
				   NETIF_F_HW_CSUM |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1061
				   NETIF_F_HW_VLAN_TX |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1062
				   NETIF_F_HW_VLAN_RX |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1063
				   NETIF_F_HW_VLAN_FILTER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1064
		if (hw->mac_type == e1000_ich8lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1065
			netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1066
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1067
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1068
	if ((hw->mac_type >= e1000_82544) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1069
	   (hw->mac_type != e1000_82547))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1070
		netdev->features |= NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1071
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1072
	if (hw->mac_type > e1000_82547_rev_2)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1073
		netdev->features |= NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1074
	if (pci_using_dac)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1075
		netdev->features |= NETIF_F_HIGHDMA;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1076
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1077
	netdev->features |= NETIF_F_LLTX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1078
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1079
	netdev->vlan_features |= NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1080
	netdev->vlan_features |= NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1081
	netdev->vlan_features |= NETIF_F_HW_CSUM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1082
	netdev->vlan_features |= NETIF_F_SG;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1083
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1084
	adapter->en_mng_pt = e1000_enable_mng_pass_thru(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1085
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1086
	/* initialize eeprom parameters */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1087
	if (e1000_init_eeprom_params(hw)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1088
		E1000_ERR("EEPROM initialization failed\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1089
		goto err_eeprom;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1090
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1091
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1092
	/* before reading the EEPROM, reset the controller to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1093
	 * put the device in a known good starting state */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1094
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1095
	e1000_reset_hw(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1096
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1097
	/* make sure the EEPROM is good */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1098
	if (e1000_validate_eeprom_checksum(hw) < 0) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1099
		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1100
		e1000_dump_eeprom(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1101
		/*
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1102
		 * set MAC address to all zeroes to invalidate and temporary
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1103
		 * disable this device for the user. This blocks regular
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1104
		 * traffic while still permitting ethtool ioctls from reaching
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1105
		 * the hardware as well as allowing the user to run the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1106
		 * interface after manually setting a hw addr using
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1107
		 * `ip set address`
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1108
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1109
		memset(hw->mac_addr, 0, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1110
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1111
		/* copy the MAC address out of the EEPROM */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1112
		if (e1000_read_mac_addr(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1113
			DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1114
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1115
	/* don't block initalization here due to bad MAC address */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1116
	memcpy(netdev->dev_addr, hw->mac_addr, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1117
	memcpy(netdev->perm_addr, hw->mac_addr, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1118
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1119
	if (!is_valid_ether_addr(netdev->perm_addr))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1120
		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1121
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1122
	e1000_get_bus_info(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1123
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1124
	init_timer(&adapter->tx_fifo_stall_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1125
	adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1126
	adapter->tx_fifo_stall_timer.data = (unsigned long)adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1127
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1128
	init_timer(&adapter->watchdog_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1129
	adapter->watchdog_timer.function = &e1000_watchdog;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1130
	adapter->watchdog_timer.data = (unsigned long) adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1131
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1132
	init_timer(&adapter->phy_info_timer);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1133
	adapter->phy_info_timer.function = &e1000_update_phy_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1134
	adapter->phy_info_timer.data = (unsigned long)adapter;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1135
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1136
	INIT_WORK(&adapter->reset_task, e1000_reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1137
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1138
	e1000_check_options(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1139
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1140
	/* Initial Wake on LAN setting
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1141
	 * If APM wake is enabled in the EEPROM,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1142
	 * enable the ACPI Magic Packet filter
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1143
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1144
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1145
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1146
	case e1000_82542_rev2_0:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1147
	case e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1148
	case e1000_82543:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1149
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1150
	case e1000_82544:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1151
		e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1152
			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1153
		eeprom_apme_mask = E1000_EEPROM_82544_APM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1154
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1155
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1156
		e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1157
			EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1158
		eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1159
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1160
	case e1000_82546:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1161
	case e1000_82546_rev_3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1162
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1163
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1164
		if (er32(STATUS) & E1000_STATUS_FUNC_1){
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1165
			e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1166
				EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1167
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1168
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1169
		/* Fall Through */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1170
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1171
		e1000_read_eeprom(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1172
			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1173
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1174
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1175
	if (eeprom_data & eeprom_apme_mask)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1176
		adapter->eeprom_wol |= E1000_WUFC_MAG;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1177
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1178
	/* now that we have the eeprom settings, apply the special cases
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1179
	 * where the eeprom may be wrong or the board simply won't support
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1180
	 * wake on lan on a particular port */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1181
	switch (pdev->device) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1182
	case E1000_DEV_ID_82546GB_PCIE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1183
		adapter->eeprom_wol = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1184
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1185
	case E1000_DEV_ID_82546EB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1186
	case E1000_DEV_ID_82546GB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1187
	case E1000_DEV_ID_82571EB_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1188
		/* Wake events only supported on port A for dual fiber
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1189
		 * regardless of eeprom setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1190
		if (er32(STATUS) & E1000_STATUS_FUNC_1)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1191
			adapter->eeprom_wol = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1192
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1193
	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1194
	case E1000_DEV_ID_82571EB_QUAD_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1195
	case E1000_DEV_ID_82571EB_QUAD_FIBER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1196
	case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1197
	case E1000_DEV_ID_82571PT_QUAD_COPPER:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1198
		/* if quad port adapter, disable WoL on all but port A */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1199
		if (global_quad_port_a != 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1200
			adapter->eeprom_wol = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1201
		else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1202
			adapter->quad_port_a = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1203
		/* Reset for multiple quad port adapters */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1204
		if (++global_quad_port_a == 4)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1205
			global_quad_port_a = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1206
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1207
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1208
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1209
	/* initialize the wol settings based on the eeprom settings */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1210
	adapter->wol = adapter->eeprom_wol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1211
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1212
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1213
	/* print bus type/speed/width info */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1214
	DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1215
		((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1216
		 (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1217
		((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1218
		 (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1219
		 (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1220
		 (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1221
		 (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1222
		((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1223
		 (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1224
		 (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1225
		 "32-bit"));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1226
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1227
	printk("%pM\n", netdev->dev_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1228
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1229
	if (hw->bus_type == e1000_bus_type_pci_express) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1230
		DPRINTK(PROBE, WARNING, "This device (id %04x:%04x) will no "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1231
			"longer be supported by this driver in the future.\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1232
			pdev->vendor, pdev->device);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1233
		DPRINTK(PROBE, WARNING, "please use the \"e1000e\" "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1234
			"driver instead.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1235
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1236
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1237
	/* reset the hardware with the new settings */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1238
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1239
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1240
	/* If the controller is 82573 and f/w is AMT, do not set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1241
	 * DRV_LOAD until the interface is up.  For all other cases,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1242
	 * let the f/w know that the h/w is now under the control
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1243
	 * of the driver. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1244
	if (hw->mac_type != e1000_82573 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1245
	    !e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1246
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1247
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1248
	// offer device to EtherCAT master module
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1249
	adapter->ecdev = ecdev_offer(netdev, ec_poll, THIS_MODULE);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1250
	if (adapter->ecdev) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1251
		err = ecdev_open(adapter->ecdev);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1252
		if (err) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1253
			ecdev_withdraw(adapter->ecdev);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1254
			goto err_register;
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1255
		}
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1256
	} else {
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1257
		/* tell the stack to leave us alone until e1000_open() is called */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1258
		netif_carrier_off(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1259
		netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1260
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1261
		strcpy(netdev->name, "eth%d");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1262
		err = register_netdev(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1263
		if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1264
			goto err_register;
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1265
	}
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1266
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1267
	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1268
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1269
	cards_found++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1270
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1271
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1272
err_register:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1273
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1274
err_eeprom:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1275
	if (!e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1276
		e1000_phy_hw_reset(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1277
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1278
	if (hw->flash_address)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1279
		iounmap(hw->flash_address);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1280
err_flashmap:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1281
	kfree(adapter->tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1282
	kfree(adapter->rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1283
err_sw_init:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1284
	iounmap(hw->hw_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1285
err_ioremap:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1286
	free_netdev(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1287
err_alloc_etherdev:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1288
	pci_release_selected_regions(pdev, bars);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1289
err_pci_reg:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1290
err_dma:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1291
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1292
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1293
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1294
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1295
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1296
 * e1000_remove - Device Removal Routine
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1297
 * @pdev: PCI device information struct
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1298
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1299
 * e1000_remove is called by the PCI subsystem to alert the driver
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1300
 * that it should release a PCI device.  The could be caused by a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1301
 * Hot-Plug event, or because the driver is going to be removed from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1302
 * memory.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1303
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1304
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1305
static void __devexit e1000_remove(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1306
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1307
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1308
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1309
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1310
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1311
	cancel_work_sync(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1312
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1313
	e1000_release_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1314
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1315
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1316
	 * would have already happened in close and is redundant. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1317
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1318
2162
3f90ae16e997 Fixed driver unloading in e1000 for 2.6.29.
Florian Pose <fp@igh-essen.com>
parents: 2072
diff changeset
  1319
	if (adapter->ecdev) {
3f90ae16e997 Fixed driver unloading in e1000 for 2.6.29.
Florian Pose <fp@igh-essen.com>
parents: 2072
diff changeset
  1320
		ecdev_close(adapter->ecdev);
3f90ae16e997 Fixed driver unloading in e1000 for 2.6.29.
Florian Pose <fp@igh-essen.com>
parents: 2072
diff changeset
  1321
		ecdev_withdraw(adapter->ecdev);
3f90ae16e997 Fixed driver unloading in e1000 for 2.6.29.
Florian Pose <fp@igh-essen.com>
parents: 2072
diff changeset
  1322
	} else {
3f90ae16e997 Fixed driver unloading in e1000 for 2.6.29.
Florian Pose <fp@igh-essen.com>
parents: 2072
diff changeset
  1323
		unregister_netdev(netdev);
3f90ae16e997 Fixed driver unloading in e1000 for 2.6.29.
Florian Pose <fp@igh-essen.com>
parents: 2072
diff changeset
  1324
	}
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1325
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1326
	if (!e1000_check_phy_reset_block(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1327
		e1000_phy_hw_reset(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1328
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1329
	kfree(adapter->tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1330
	kfree(adapter->rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1331
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1332
	iounmap(hw->hw_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1333
	if (hw->flash_address)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1334
		iounmap(hw->flash_address);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1335
	pci_release_selected_regions(pdev, adapter->bars);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1336
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1337
	free_netdev(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1338
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1339
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1340
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1341
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1342
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1343
 * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1344
 * @adapter: board private structure to initialize
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1345
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1346
 * e1000_sw_init initializes the Adapter private data structure.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1347
 * Fields are initialized based on PCI device information and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1348
 * OS network device settings (MTU size).
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1349
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1350
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1351
static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1352
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1353
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1354
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1355
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1356
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1357
	/* PCI config space info */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1358
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1359
	hw->vendor_id = pdev->vendor;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1360
	hw->device_id = pdev->device;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1361
	hw->subsystem_vendor_id = pdev->subsystem_vendor;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1362
	hw->subsystem_id = pdev->subsystem_device;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1363
	hw->revision_id = pdev->revision;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1364
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1365
	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1366
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1367
	adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1368
	hw->max_frame_size = netdev->mtu +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1369
			     ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1370
	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1371
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1372
	/* identify the MAC */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1373
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1374
	if (e1000_set_mac_type(hw)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1375
		DPRINTK(PROBE, ERR, "Unknown MAC Type\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1376
		return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1377
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1378
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1379
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1380
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1381
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1382
	case e1000_82541:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1383
	case e1000_82547:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1384
	case e1000_82541_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1385
	case e1000_82547_rev_2:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1386
		hw->phy_init_script = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1387
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1388
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1389
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1390
	e1000_set_media_type(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1391
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1392
	hw->wait_autoneg_complete = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1393
	hw->tbi_compatibility_en = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1394
	hw->adaptive_ifs = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1395
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1396
	/* Copper options */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1397
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1398
	if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1399
		hw->mdix = AUTO_ALL_MODES;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1400
		hw->disable_polarity_correction = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1401
		hw->master_slave = E1000_MASTER_SLAVE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1402
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1403
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1404
	adapter->num_tx_queues = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1405
	adapter->num_rx_queues = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1406
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1407
	if (e1000_alloc_queues(adapter)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1408
		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1409
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1410
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1411
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1412
	spin_lock_init(&adapter->tx_queue_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1413
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1414
	/* Explicitly disable IRQ since the NIC can be in any state. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1415
	e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1416
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1417
	spin_lock_init(&adapter->stats_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1418
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1419
	set_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1420
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1421
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1422
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1423
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1424
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1425
 * e1000_alloc_queues - Allocate memory for all rings
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1426
 * @adapter: board private structure to initialize
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1427
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1428
 * We allocate one ring per queue at run-time since we don't know the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1429
 * number of queues at compile-time.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1430
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1431
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1432
static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1433
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1434
	adapter->tx_ring = kcalloc(adapter->num_tx_queues,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1435
	                           sizeof(struct e1000_tx_ring), GFP_KERNEL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1436
	if (!adapter->tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1437
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1438
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1439
	adapter->rx_ring = kcalloc(adapter->num_rx_queues,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1440
	                           sizeof(struct e1000_rx_ring), GFP_KERNEL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1441
	if (!adapter->rx_ring) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1442
		kfree(adapter->tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1443
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1444
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1445
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1446
	return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1447
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1448
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1449
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1450
 * e1000_open - Called when a network interface is made active
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1451
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1452
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1453
 * Returns 0 on success, negative value on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1454
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1455
 * The open entry point is called when a network interface is made
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1456
 * active by the system (IFF_UP).  At this point all resources needed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1457
 * for transmit and receive operations are allocated, the interrupt
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1458
 * handler is registered with the OS, the watchdog timer is started,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1459
 * and the stack is notified that the interface is ready.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1460
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1461
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1462
static int e1000_open(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1463
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1464
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1465
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1466
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1467
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1468
	/* disallow open during test */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1469
	if (test_bit(__E1000_TESTING, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1470
		return -EBUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1471
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1472
	/* allocate transmit descriptors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1473
	err = e1000_setup_all_tx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1474
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1475
		goto err_setup_tx;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1476
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1477
	/* allocate receive descriptors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1478
	err = e1000_setup_all_rx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1479
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1480
		goto err_setup_rx;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1481
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1482
	e1000_power_up_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1483
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1484
	adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1485
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1486
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1487
		e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1488
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1489
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1490
	/* If AMT is enabled, let the firmware know that the network
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1491
	 * interface is now open */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1492
	if (hw->mac_type == e1000_82573 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1493
	    e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1494
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1495
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1496
	/* before we allocate an interrupt, we must be ready to handle it.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1497
	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1498
	 * as soon as we call pci_request_irq, so we have to setup our
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1499
	 * clean_rx handler before we do so.  */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1500
	e1000_configure(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1501
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1502
	err = e1000_request_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1503
	if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1504
		goto err_req_irq;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1505
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1506
	/* From here on the code is the same as e1000_up() */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1507
	clear_bit(__E1000_DOWN, &adapter->flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1508
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1509
	if (!adapter->ecdev) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1510
		napi_enable(&adapter->napi);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1511
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1512
		e1000_irq_enable(adapter);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1513
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1514
		netif_start_queue(netdev);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  1515
	}
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1516
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1517
	/* fire a link status change interrupt to start the watchdog */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1518
	ew32(ICS, E1000_ICS_LSC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1519
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1520
	return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1521
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1522
err_req_irq:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1523
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1524
	e1000_power_down_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1525
	e1000_free_all_rx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1526
err_setup_rx:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1527
	e1000_free_all_tx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1528
err_setup_tx:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1529
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1530
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1531
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1532
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1533
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1534
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1535
 * e1000_close - Disables a network interface
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1536
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1537
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1538
 * Returns 0, this is not allowed to fail
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1539
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1540
 * The close entry point is called when an interface is de-activated
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1541
 * by the OS.  The hardware is still under the drivers control, but
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1542
 * needs to be disabled.  A global MAC reset is issued to stop the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1543
 * hardware, and all transmit and receive resources are freed.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1544
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1545
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1546
static int e1000_close(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1547
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1548
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1549
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1550
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1551
	WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1552
	e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1553
	e1000_power_down_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1554
	e1000_free_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1555
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1556
	e1000_free_all_tx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1557
	e1000_free_all_rx_resources(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1558
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1559
	/* kill manageability vlan ID if supported, but not if a vlan with
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1560
	 * the same ID is registered on the host OS (let 8021q kill it) */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1561
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1562
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1563
	     !(adapter->vlgrp &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1564
	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1565
		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1566
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1567
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1568
	/* If AMT is enabled, let the firmware know that the network
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1569
	 * interface is now closed */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1570
	if (hw->mac_type == e1000_82573 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1571
	    e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1572
		e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1573
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1574
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1575
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1576
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1577
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1578
 * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1579
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1580
 * @start: address of beginning of memory
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1581
 * @len: length of memory
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1582
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1583
static bool e1000_check_64k_bound(struct e1000_adapter *adapter, void *start,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1584
				  unsigned long len)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1585
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1586
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1587
	unsigned long begin = (unsigned long)start;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1588
	unsigned long end = begin + len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1589
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1590
	/* First rev 82545 and 82546 need to not allow any memory
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1591
	 * write location to cross 64k boundary due to errata 23 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1592
	if (hw->mac_type == e1000_82545 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1593
	    hw->mac_type == e1000_82546) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1594
		return ((begin ^ (end - 1)) >> 16) != 0 ? false : true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1595
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1596
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1597
	return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1598
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1599
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1600
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1601
 * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1602
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1603
 * @txdr:    tx descriptor ring (for a specific queue) to setup
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1604
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1605
 * Return 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1606
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1607
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1608
static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1609
				    struct e1000_tx_ring *txdr)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1610
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1611
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1612
	int size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1613
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1614
	size = sizeof(struct e1000_buffer) * txdr->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1615
	txdr->buffer_info = vmalloc(size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1616
	if (!txdr->buffer_info) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1617
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1618
		"Unable to allocate memory for the transmit descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1619
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1620
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1621
	memset(txdr->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1622
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1623
	/* round up to nearest 4K */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1624
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1625
	txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1626
	txdr->size = ALIGN(txdr->size, 4096);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1627
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1628
	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1629
	if (!txdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1630
setup_tx_desc_die:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1631
		vfree(txdr->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1632
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1633
		"Unable to allocate memory for the transmit descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1634
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1635
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1636
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1637
	/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1638
	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1639
		void *olddesc = txdr->desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1640
		dma_addr_t olddma = txdr->dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1641
		DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1642
				     "at %p\n", txdr->size, txdr->desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1643
		/* Try again, without freeing the previous */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1644
		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1645
		/* Failed allocation, critical failure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1646
		if (!txdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1647
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1648
			goto setup_tx_desc_die;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1649
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1650
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1651
		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1652
			/* give up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1653
			pci_free_consistent(pdev, txdr->size, txdr->desc,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1654
					    txdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1655
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1656
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1657
				"Unable to allocate aligned memory "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1658
				"for the transmit descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1659
			vfree(txdr->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1660
			return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1661
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1662
			/* Free old allocation, new allocation was successful */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1663
			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1664
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1665
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1666
	memset(txdr->desc, 0, txdr->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1667
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1668
	txdr->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1669
	txdr->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1670
	spin_lock_init(&txdr->tx_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1671
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1672
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1673
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1674
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1675
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1676
 * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1677
 * 				  (Descriptors) for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1678
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1679
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1680
 * Return 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1681
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1682
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1683
int e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1684
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1685
	int i, err = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1686
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1687
	for (i = 0; i < adapter->num_tx_queues; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1688
		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1689
		if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1690
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1691
				"Allocation for Tx Queue %u failed\n", i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1692
			for (i-- ; i >= 0; i--)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1693
				e1000_free_tx_resources(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1694
							&adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1695
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1696
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1697
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1698
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1699
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1700
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1701
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1702
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1703
 * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1704
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1705
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1706
 * Configure the Tx unit of the MAC after a reset.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1707
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1708
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1709
static void e1000_configure_tx(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1710
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1711
	u64 tdba;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1712
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1713
	u32 tdlen, tctl, tipg, tarc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1714
	u32 ipgr1, ipgr2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1715
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1716
	/* Setup the HW Tx Head and Tail descriptor pointers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1717
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1718
	switch (adapter->num_tx_queues) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1719
	case 1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1720
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1721
		tdba = adapter->tx_ring[0].dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1722
		tdlen = adapter->tx_ring[0].count *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1723
			sizeof(struct e1000_tx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1724
		ew32(TDLEN, tdlen);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1725
		ew32(TDBAH, (tdba >> 32));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1726
		ew32(TDBAL, (tdba & 0x00000000ffffffffULL));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1727
		ew32(TDT, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1728
		ew32(TDH, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1729
		adapter->tx_ring[0].tdh = ((hw->mac_type >= e1000_82543) ? E1000_TDH : E1000_82542_TDH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1730
		adapter->tx_ring[0].tdt = ((hw->mac_type >= e1000_82543) ? E1000_TDT : E1000_82542_TDT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1731
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1732
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1733
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1734
	/* Set the default values for the Tx Inter Packet Gap timer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1735
	if (hw->mac_type <= e1000_82547_rev_2 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1736
	    (hw->media_type == e1000_media_type_fiber ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1737
	     hw->media_type == e1000_media_type_internal_serdes))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1738
		tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1739
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1740
		tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1741
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1742
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1743
	case e1000_82542_rev2_0:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1744
	case e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1745
		tipg = DEFAULT_82542_TIPG_IPGT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1746
		ipgr1 = DEFAULT_82542_TIPG_IPGR1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1747
		ipgr2 = DEFAULT_82542_TIPG_IPGR2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1748
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1749
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1750
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1751
		ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1752
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1753
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1754
		ipgr1 = DEFAULT_82543_TIPG_IPGR1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1755
		ipgr2 = DEFAULT_82543_TIPG_IPGR2;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1756
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1757
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1758
	tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1759
	tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1760
	ew32(TIPG, tipg);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1761
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1762
	/* Set the Tx Interrupt Delay register */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1763
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1764
	ew32(TIDV, adapter->tx_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1765
	if (hw->mac_type >= e1000_82540)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1766
		ew32(TADV, adapter->tx_abs_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1767
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1768
	/* Program the Transmit Control Register */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1769
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1770
	tctl = er32(TCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1771
	tctl &= ~E1000_TCTL_CT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1772
	tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1773
		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1774
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1775
	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1776
		tarc = er32(TARC0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1777
		/* set the speed mode bit, we'll clear it if we're not at
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1778
		 * gigabit link later */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1779
		tarc |= (1 << 21);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1780
		ew32(TARC0, tarc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1781
	} else if (hw->mac_type == e1000_80003es2lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1782
		tarc = er32(TARC0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1783
		tarc |= 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1784
		ew32(TARC0, tarc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1785
		tarc = er32(TARC1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1786
		tarc |= 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1787
		ew32(TARC1, tarc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1788
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1789
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1790
	e1000_config_collision_dist(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1791
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1792
	/* Setup Transmit Descriptor Settings for eop descriptor */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1793
	adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1794
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1795
	/* only set IDE if we are delaying interrupts using the timers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1796
	if (adapter->tx_int_delay)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1797
		adapter->txd_cmd |= E1000_TXD_CMD_IDE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1798
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1799
	if (hw->mac_type < e1000_82543)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1800
		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1801
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1802
		adapter->txd_cmd |= E1000_TXD_CMD_RS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1803
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1804
	/* Cache if we're 82544 running in PCI-X because we'll
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1805
	 * need this to apply a workaround later in the send path. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1806
	if (hw->mac_type == e1000_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1807
	    hw->bus_type == e1000_bus_type_pcix)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1808
		adapter->pcix_82544 = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1809
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1810
	ew32(TCTL, tctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1811
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1812
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1813
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1814
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1815
 * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1816
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1817
 * @rxdr:    rx descriptor ring (for a specific queue) to setup
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1818
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1819
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1820
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1821
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1822
static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1823
				    struct e1000_rx_ring *rxdr)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1824
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1825
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1826
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1827
	int size, desc_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1828
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1829
	size = sizeof(struct e1000_buffer) * rxdr->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1830
	rxdr->buffer_info = vmalloc(size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1831
	if (!rxdr->buffer_info) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1832
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1833
		"Unable to allocate memory for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1834
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1835
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1836
	memset(rxdr->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1837
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1838
	if (hw->mac_type <= e1000_82547_rev_2)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1839
		desc_len = sizeof(struct e1000_rx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1840
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1841
		desc_len = sizeof(union e1000_rx_desc_packet_split);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1842
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1843
	/* Round up to nearest 4K */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1844
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1845
	rxdr->size = rxdr->count * desc_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1846
	rxdr->size = ALIGN(rxdr->size, 4096);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1847
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1848
	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1849
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1850
	if (!rxdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1851
		DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1852
		"Unable to allocate memory for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1853
setup_rx_desc_die:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1854
		vfree(rxdr->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1855
		return -ENOMEM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1856
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1857
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1858
	/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1859
	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1860
		void *olddesc = rxdr->desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1861
		dma_addr_t olddma = rxdr->dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1862
		DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1863
				     "at %p\n", rxdr->size, rxdr->desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1864
		/* Try again, without freeing the previous */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1865
		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1866
		/* Failed allocation, critical failure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1867
		if (!rxdr->desc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1868
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1869
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1870
				"Unable to allocate memory "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1871
				"for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1872
			goto setup_rx_desc_die;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1873
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1874
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1875
		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1876
			/* give up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1877
			pci_free_consistent(pdev, rxdr->size, rxdr->desc,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1878
					    rxdr->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1879
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1880
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1881
				"Unable to allocate aligned memory "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1882
				"for the receive descriptor ring\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1883
			goto setup_rx_desc_die;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1884
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1885
			/* Free old allocation, new allocation was successful */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1886
			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1887
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1888
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1889
	memset(rxdr->desc, 0, rxdr->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1890
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1891
	rxdr->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1892
	rxdr->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1893
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1894
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1895
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1896
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1897
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1898
 * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1899
 * 				  (Descriptors) for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1900
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1901
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1902
 * Return 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1903
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1904
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1905
int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1906
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1907
	int i, err = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1908
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1909
	for (i = 0; i < adapter->num_rx_queues; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1910
		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1911
		if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1912
			DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1913
				"Allocation for Rx Queue %u failed\n", i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1914
			for (i-- ; i >= 0; i--)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1915
				e1000_free_rx_resources(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1916
							&adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1917
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1918
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1919
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1920
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1921
	return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1922
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1923
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1924
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1925
 * e1000_setup_rctl - configure the receive control registers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1926
 * @adapter: Board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1927
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1928
#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1929
			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1930
static void e1000_setup_rctl(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1931
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1932
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1933
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1934
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1935
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1936
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1937
	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1938
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1939
	rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1940
		E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1941
		(hw->mc_filter_type << E1000_RCTL_MO_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1942
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1943
	if (hw->tbi_compatibility_on == 1)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1944
		rctl |= E1000_RCTL_SBP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1945
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1946
		rctl &= ~E1000_RCTL_SBP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1947
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1948
	if (adapter->netdev->mtu <= ETH_DATA_LEN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1949
		rctl &= ~E1000_RCTL_LPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1950
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1951
		rctl |= E1000_RCTL_LPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1952
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1953
	/* Setup buffer sizes */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1954
	rctl &= ~E1000_RCTL_SZ_4096;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1955
	rctl |= E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1956
	switch (adapter->rx_buffer_len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1957
		case E1000_RXBUFFER_256:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1958
			rctl |= E1000_RCTL_SZ_256;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1959
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1960
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1961
		case E1000_RXBUFFER_512:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1962
			rctl |= E1000_RCTL_SZ_512;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1963
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1964
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1965
		case E1000_RXBUFFER_1024:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1966
			rctl |= E1000_RCTL_SZ_1024;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1967
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1968
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1969
		case E1000_RXBUFFER_2048:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1970
		default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1971
			rctl |= E1000_RCTL_SZ_2048;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1972
			rctl &= ~E1000_RCTL_BSEX;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1973
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1974
		case E1000_RXBUFFER_4096:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1975
			rctl |= E1000_RCTL_SZ_4096;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1976
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1977
		case E1000_RXBUFFER_8192:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1978
			rctl |= E1000_RCTL_SZ_8192;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1979
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1980
		case E1000_RXBUFFER_16384:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1981
			rctl |= E1000_RCTL_SZ_16384;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1982
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1983
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1984
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1985
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1986
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1987
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1988
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1989
 * e1000_configure_rx - Configure 8254x Receive Unit after Reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1990
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1991
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1992
 * Configure the Rx unit of the MAC after a reset.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1993
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1994
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1995
static void e1000_configure_rx(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1996
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1997
	u64 rdba;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1998
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  1999
	u32 rdlen, rctl, rxcsum, ctrl_ext;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2001
	rdlen = adapter->rx_ring[0].count *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2002
		sizeof(struct e1000_rx_desc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2003
	adapter->clean_rx = e1000_clean_rx_irq;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2004
	adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2005
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2006
	/* disable receives while setting up the descriptors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2007
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2008
	ew32(RCTL, rctl & ~E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2009
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2010
	/* set the Receive Delay Timer Register */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2011
	ew32(RDTR, adapter->rx_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2012
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2013
	if (hw->mac_type >= e1000_82540) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2014
		ew32(RADV, adapter->rx_abs_int_delay);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2015
		if (adapter->itr_setting != 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2016
			ew32(ITR, 1000000000 / (adapter->itr * 256));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2017
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2018
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2019
	if (hw->mac_type >= e1000_82571) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2020
		ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2021
		/* Reset delay timers after every interrupt */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2022
		ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2023
		/* Auto-Mask interrupts upon ICR access */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2024
		ctrl_ext |= E1000_CTRL_EXT_IAME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2025
		ew32(IAM, 0xffffffff);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2026
		ew32(CTRL_EXT, ctrl_ext);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2027
		E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2028
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2029
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2030
	/* Setup the HW Rx Head and Tail Descriptor Pointers and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2031
	 * the Base and Length of the Rx Descriptor Ring */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2032
	switch (adapter->num_rx_queues) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2033
	case 1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2034
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2035
		rdba = adapter->rx_ring[0].dma;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2036
		ew32(RDLEN, rdlen);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2037
		ew32(RDBAH, (rdba >> 32));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2038
		ew32(RDBAL, (rdba & 0x00000000ffffffffULL));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2039
		ew32(RDT, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2040
		ew32(RDH, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2041
		adapter->rx_ring[0].rdh = ((hw->mac_type >= e1000_82543) ? E1000_RDH : E1000_82542_RDH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2042
		adapter->rx_ring[0].rdt = ((hw->mac_type >= e1000_82543) ? E1000_RDT : E1000_82542_RDT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2043
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2044
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2045
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2046
	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2047
	if (hw->mac_type >= e1000_82543) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2048
		rxcsum = er32(RXCSUM);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2049
		if (adapter->rx_csum)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2050
			rxcsum |= E1000_RXCSUM_TUOFL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2051
		else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2052
			/* don't need to clear IPPCSE as it defaults to 0 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2053
			rxcsum &= ~E1000_RXCSUM_TUOFL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2054
		ew32(RXCSUM, rxcsum);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2055
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2056
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2057
	/* Enable Receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2058
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2059
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2060
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2061
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2062
 * e1000_free_tx_resources - Free Tx Resources per Queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2063
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2064
 * @tx_ring: Tx descriptor ring for a specific queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2065
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2066
 * Free all transmit software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2067
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2068
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2069
static void e1000_free_tx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2070
				    struct e1000_tx_ring *tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2071
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2072
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2073
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2074
	e1000_clean_tx_ring(adapter, tx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2075
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2076
	vfree(tx_ring->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2077
	tx_ring->buffer_info = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2078
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2079
	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2080
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2081
	tx_ring->desc = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2082
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2083
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2084
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2085
 * e1000_free_all_tx_resources - Free Tx Resources for All Queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2086
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2087
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2088
 * Free all transmit software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2089
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2090
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2091
void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2092
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2093
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2094
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2095
	for (i = 0; i < adapter->num_tx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2096
		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2097
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2098
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2099
static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2100
					     struct e1000_buffer *buffer_info)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2101
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2102
	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2103
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2104
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2105
	if (buffer_info->dma) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2106
		pci_unmap_page(adapter->pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2107
				buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2108
				buffer_info->length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2109
				PCI_DMA_TODEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2110
		buffer_info->dma = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2111
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2112
	if (buffer_info->skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2113
		dev_kfree_skb_any(buffer_info->skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2114
		buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2115
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2116
	/* buffer_info must be completely set up in the transmit path */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2117
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2118
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2119
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2120
 * e1000_clean_tx_ring - Free Tx Buffers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2121
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2122
 * @tx_ring: ring to be cleaned
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2123
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2124
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2125
static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2126
				struct e1000_tx_ring *tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2127
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2128
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2129
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2130
	unsigned long size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2131
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2132
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2133
	/* Free all the Tx ring sk_buffs */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2134
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2135
	for (i = 0; i < tx_ring->count; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2136
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2137
		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2138
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2139
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2140
	size = sizeof(struct e1000_buffer) * tx_ring->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2141
	memset(tx_ring->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2142
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2143
	/* Zero out the descriptor ring */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2144
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2145
	memset(tx_ring->desc, 0, tx_ring->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2146
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2147
	tx_ring->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2148
	tx_ring->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2149
	tx_ring->last_tx_tso = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2150
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2151
	writel(0, hw->hw_addr + tx_ring->tdh);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2152
	writel(0, hw->hw_addr + tx_ring->tdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2153
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2154
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2155
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2156
 * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2157
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2158
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2159
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2160
static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2161
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2162
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2163
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2164
	for (i = 0; i < adapter->num_tx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2165
		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2166
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2167
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2168
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2169
 * e1000_free_rx_resources - Free Rx Resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2170
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2171
 * @rx_ring: ring to clean the resources from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2172
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2173
 * Free all receive software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2174
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2175
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2176
static void e1000_free_rx_resources(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2177
				    struct e1000_rx_ring *rx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2178
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2179
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2180
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2181
	e1000_clean_rx_ring(adapter, rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2182
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2183
	vfree(rx_ring->buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2184
	rx_ring->buffer_info = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2185
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2186
	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2187
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2188
	rx_ring->desc = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2189
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2190
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2191
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2192
 * e1000_free_all_rx_resources - Free Rx Resources for All Queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2193
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2194
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2195
 * Free all receive software resources
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2196
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2197
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2198
void e1000_free_all_rx_resources(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2199
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2200
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2201
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2202
	for (i = 0; i < adapter->num_rx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2203
		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2204
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2205
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2206
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2207
 * e1000_clean_rx_ring - Free Rx Buffers per Queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2208
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2209
 * @rx_ring: ring to free buffers from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2210
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2211
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2212
static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2213
				struct e1000_rx_ring *rx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2214
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2215
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2216
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2217
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2218
	unsigned long size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2219
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2220
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2221
	/* Free all the Rx ring sk_buffs */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2222
	for (i = 0; i < rx_ring->count; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2223
		buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2224
		if (buffer_info->skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2225
			pci_unmap_single(pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2226
					 buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2227
					 buffer_info->length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2228
					 PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2229
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2230
			dev_kfree_skb(buffer_info->skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2231
			buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2232
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2233
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2234
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2235
	size = sizeof(struct e1000_buffer) * rx_ring->count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2236
	memset(rx_ring->buffer_info, 0, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2237
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2238
	/* Zero out the descriptor ring */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2239
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2240
	memset(rx_ring->desc, 0, rx_ring->size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2241
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2242
	rx_ring->next_to_clean = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2243
	rx_ring->next_to_use = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2244
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2245
	writel(0, hw->hw_addr + rx_ring->rdh);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2246
	writel(0, hw->hw_addr + rx_ring->rdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2247
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2248
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2249
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2250
 * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2251
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2252
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2253
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2254
static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2255
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2256
	int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2257
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2258
	for (i = 0; i < adapter->num_rx_queues; i++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2259
		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2260
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2261
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2262
/* The 82542 2.0 (revision 2) needs to have the receive unit in reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2263
 * and memory write and invalidate disabled for certain operations
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2264
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2265
static void e1000_enter_82542_rst(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2266
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2267
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2268
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2269
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2270
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2271
	e1000_pci_clear_mwi(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2272
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2273
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2274
	rctl |= E1000_RCTL_RST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2275
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2276
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2277
	mdelay(5);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2278
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2279
	if (!adapter->ecdev && netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2280
		e1000_clean_all_rx_rings(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2281
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2282
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2283
static void e1000_leave_82542_rst(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2284
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2285
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2286
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2287
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2288
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2289
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2290
	rctl &= ~E1000_RCTL_RST;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2291
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2292
	E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2293
	mdelay(5);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2294
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2295
	if (hw->pci_cmd_word & PCI_COMMAND_INVALIDATE)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2296
		e1000_pci_set_mwi(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2297
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2298
	if (!adapter->netdev && netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2299
		/* No need to loop, because 82542 supports only 1 queue */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2300
		struct e1000_rx_ring *ring = &adapter->rx_ring[0];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2301
		e1000_configure_rx(adapter);
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  2302
		if (adapter->ecdev) {
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2303
			/* fill rx ring completely! */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2304
			adapter->alloc_rx_buf(adapter, ring, ring->count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2305
		} else {
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  2306
			/* this one leaves the last ring element unallocated! */
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2307
			adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2308
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2309
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2310
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2311
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2312
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2313
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2314
 * e1000_set_mac - Change the Ethernet Address of the NIC
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2315
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2316
 * @p: pointer to an address structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2317
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2318
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2319
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2320
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2321
static int e1000_set_mac(struct net_device *netdev, void *p)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2322
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2323
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2324
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2325
	struct sockaddr *addr = p;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2326
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2327
	if (!is_valid_ether_addr(addr->sa_data))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2328
		return -EADDRNOTAVAIL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2329
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2330
	/* 82542 2.0 needs to be in reset to write receive address registers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2331
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2332
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2333
		e1000_enter_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2334
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2335
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2336
	memcpy(hw->mac_addr, addr->sa_data, netdev->addr_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2337
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2338
	e1000_rar_set(hw, hw->mac_addr, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2339
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2340
	/* With 82571 controllers, LAA may be overwritten (with the default)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2341
	 * due to controller reset from the other port. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2342
	if (hw->mac_type == e1000_82571) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2343
		/* activate the work around */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2344
		hw->laa_is_present = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2345
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2346
		/* Hold a copy of the LAA in RAR[14] This is done so that
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2347
		 * between the time RAR[0] gets clobbered  and the time it
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2348
		 * gets fixed (in e1000_watchdog), the actual LAA is in one
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2349
		 * of the RARs and no incoming packets directed to this port
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2350
		 * are dropped. Eventaully the LAA will be in RAR[0] and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2351
		 * RAR[14] */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2352
		e1000_rar_set(hw, hw->mac_addr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2353
					E1000_RAR_ENTRIES - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2354
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2355
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2356
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2357
		e1000_leave_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2358
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2359
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2360
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2361
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2362
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2363
 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2364
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2365
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2366
 * The set_rx_mode entry point is called whenever the unicast or multicast
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2367
 * address lists or the network interface flags are updated. This routine is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2368
 * responsible for configuring the hardware for proper unicast, multicast,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2369
 * promiscuous mode, and all-multi behavior.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2370
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2371
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2372
static void e1000_set_rx_mode(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2373
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2374
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2375
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2376
	struct dev_addr_list *uc_ptr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2377
	struct dev_addr_list *mc_ptr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2378
	u32 rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2379
	u32 hash_value;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2380
	int i, rar_entries = E1000_RAR_ENTRIES;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2381
	int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2382
				E1000_NUM_MTA_REGISTERS_ICH8LAN :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2383
				E1000_NUM_MTA_REGISTERS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2384
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2385
	if (hw->mac_type == e1000_ich8lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2386
		rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2387
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2388
	/* reserve RAR[14] for LAA over-write work-around */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2389
	if (hw->mac_type == e1000_82571)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2390
		rar_entries--;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2391
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2392
	/* Check for Promiscuous and All Multicast modes */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2393
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2394
	rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2395
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2396
	if (netdev->flags & IFF_PROMISC) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2397
		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2398
		rctl &= ~E1000_RCTL_VFE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2399
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2400
		if (netdev->flags & IFF_ALLMULTI) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2401
			rctl |= E1000_RCTL_MPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2402
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2403
			rctl &= ~E1000_RCTL_MPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2404
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2405
		if (adapter->hw.mac_type != e1000_ich8lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2406
			rctl |= E1000_RCTL_VFE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2407
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2408
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2409
	uc_ptr = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2410
	if (netdev->uc_count > rar_entries - 1) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2411
		rctl |= E1000_RCTL_UPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2412
	} else if (!(netdev->flags & IFF_PROMISC)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2413
		rctl &= ~E1000_RCTL_UPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2414
		uc_ptr = netdev->uc_list;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2415
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2416
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2417
	ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2418
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2419
	/* 82542 2.0 needs to be in reset to write receive address registers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2420
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2421
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2422
		e1000_enter_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2423
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2424
	/* load the first 14 addresses into the exact filters 1-14. Unicast
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2425
	 * addresses take precedence to avoid disabling unicast filtering
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2426
	 * when possible.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2427
	 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2428
	 * RAR 0 is used for the station MAC adddress
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2429
	 * if there are not 14 addresses, go ahead and clear the filters
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2430
	 * -- with 82571 controllers only 0-13 entries are filled here
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2431
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2432
	mc_ptr = netdev->mc_list;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2433
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2434
	for (i = 1; i < rar_entries; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2435
		if (uc_ptr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2436
			e1000_rar_set(hw, uc_ptr->da_addr, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2437
			uc_ptr = uc_ptr->next;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2438
		} else if (mc_ptr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2439
			e1000_rar_set(hw, mc_ptr->da_addr, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2440
			mc_ptr = mc_ptr->next;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2441
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2442
			E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2443
			E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2444
			E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2445
			E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2446
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2447
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2448
	WARN_ON(uc_ptr != NULL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2449
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2450
	/* clear the old settings from the multicast hash table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2451
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2452
	for (i = 0; i < mta_reg_count; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2453
		E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2454
		E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2455
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2456
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2457
	/* load any remaining addresses into the hash table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2458
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2459
	for (; mc_ptr; mc_ptr = mc_ptr->next) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2460
		hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2461
		e1000_mta_set(hw, hash_value);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2462
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2463
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2464
	if (hw->mac_type == e1000_82542_rev2_0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2465
		e1000_leave_82542_rst(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2466
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2467
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2468
/* Need to wait a few seconds after link up to get diagnostic information from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2469
 * the phy */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2470
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2471
static void e1000_update_phy_info(unsigned long data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2472
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2473
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2474
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2475
	e1000_phy_get_info(hw, &adapter->phy_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2476
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2477
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2478
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2479
 * e1000_82547_tx_fifo_stall - Timer Call-back
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2480
 * @data: pointer to adapter cast into an unsigned long
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2481
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2482
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2483
static void e1000_82547_tx_fifo_stall(unsigned long data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2484
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2485
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2486
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2487
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2488
	u32 tctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2489
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2490
	if (atomic_read(&adapter->tx_fifo_stall)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2491
		if ((er32(TDT) == er32(TDH)) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2492
		   (er32(TDFT) == er32(TDFH)) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2493
		   (er32(TDFTS) == er32(TDFHS))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2494
			tctl = er32(TCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2495
			ew32(TCTL, tctl & ~E1000_TCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2496
			ew32(TDFT, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2497
			ew32(TDFH, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2498
			ew32(TDFTS, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2499
			ew32(TDFHS, adapter->tx_head_addr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2500
			ew32(TCTL, tctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2501
			E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2502
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2503
			adapter->tx_fifo_head = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2504
			atomic_set(&adapter->tx_fifo_stall, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2505
			if (!adapter->ecdev) netif_wake_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2506
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2507
			if (!adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2508
				mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2509
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2510
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2511
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2512
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2513
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2514
 * e1000_watchdog - Timer Call-back
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2515
 * @data: pointer to adapter cast into an unsigned long
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2516
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2517
static void e1000_watchdog(unsigned long data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2518
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2519
	struct e1000_adapter *adapter = (struct e1000_adapter *)data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2520
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2521
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2522
	struct e1000_tx_ring *txdr = adapter->tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2523
	u32 link, tctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2524
	s32 ret_val;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2525
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2526
	ret_val = e1000_check_for_link(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2527
	if ((ret_val == E1000_ERR_PHY) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2528
	    (hw->phy_type == e1000_phy_igp_3) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2529
	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2530
		/* See e1000_kumeran_lock_loss_workaround() */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2531
		DPRINTK(LINK, INFO,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2532
			"Gigabit has been disabled, downgrading speed\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2533
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2534
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2535
	if (hw->mac_type == e1000_82573) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2536
		e1000_enable_tx_pkt_filtering(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2537
		if (adapter->mng_vlan_id != hw->mng_cookie.vlan_id)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2538
			e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2539
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2540
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2541
	if ((hw->media_type == e1000_media_type_internal_serdes) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2542
	   !(er32(TXCW) & E1000_TXCW_ANE))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2543
		link = !hw->serdes_link_down;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2544
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2545
		link = er32(STATUS) & E1000_STATUS_LU;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2546
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2547
	if (link) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2548
		if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2549
				|| (!adapter->ecdev && !netif_carrier_ok(netdev))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2550
			u32 ctrl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2551
			bool txb2b = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2552
			e1000_get_speed_and_duplex(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2553
			                           &adapter->link_speed,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2554
			                           &adapter->link_duplex);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2555
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2556
			ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2557
			printk(KERN_INFO "e1000: %s NIC Link is Up %d Mbps %s, "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2558
			       "Flow Control: %s\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2559
			       netdev->name,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2560
			       adapter->link_speed,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2561
			       adapter->link_duplex == FULL_DUPLEX ?
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2562
			        "Full Duplex" : "Half Duplex",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2563
			        ((ctrl & E1000_CTRL_TFCE) && (ctrl &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2564
			        E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2565
			        E1000_CTRL_RFCE) ? "RX" : ((ctrl &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2566
			        E1000_CTRL_TFCE) ? "TX" : "None" )));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2567
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2568
			/* tweak tx_queue_len according to speed/duplex
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2569
			 * and adjust the timeout factor */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2570
			netdev->tx_queue_len = adapter->tx_queue_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2571
			adapter->tx_timeout_factor = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2572
			switch (adapter->link_speed) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2573
			case SPEED_10:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2574
				txb2b = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2575
				netdev->tx_queue_len = 10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2576
				adapter->tx_timeout_factor = 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2577
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2578
			case SPEED_100:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2579
				txb2b = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2580
				netdev->tx_queue_len = 100;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2581
				/* maybe add some timeout factor ? */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2582
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2583
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2584
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2585
			if ((hw->mac_type == e1000_82571 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2586
			     hw->mac_type == e1000_82572) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2587
			    !txb2b) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2588
				u32 tarc0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2589
				tarc0 = er32(TARC0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2590
				tarc0 &= ~(1 << 21);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2591
				ew32(TARC0, tarc0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2592
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2593
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2594
			/* disable TSO for pcie and 10/100 speeds, to avoid
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2595
			 * some hardware issues */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2596
			if (!adapter->tso_force &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2597
			    hw->bus_type == e1000_bus_type_pci_express){
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2598
				switch (adapter->link_speed) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2599
				case SPEED_10:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2600
				case SPEED_100:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2601
					DPRINTK(PROBE,INFO,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2602
				        "10/100 speed: disabling TSO\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2603
					netdev->features &= ~NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2604
					netdev->features &= ~NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2605
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2606
				case SPEED_1000:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2607
					netdev->features |= NETIF_F_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2608
					netdev->features |= NETIF_F_TSO6;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2609
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2610
				default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2611
					/* oops */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2612
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2613
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2614
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2615
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2616
			/* enable transmits in the hardware, need to do this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2617
			 * after setting TARC0 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2618
			tctl = er32(TCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2619
			tctl |= E1000_TCTL_EN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2620
			ew32(TCTL, tctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2621
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2622
			if (adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2623
				ecdev_set_link(adapter->ecdev, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2624
			} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2625
				netif_carrier_on(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2626
				netif_wake_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2627
				mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2628
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2629
			adapter->smartspeed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2630
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2631
			/* make sure the receive unit is started */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2632
			if (hw->rx_needs_kicking) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2633
				u32 rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2634
				ew32(RCTL, rctl | E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2635
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2636
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2637
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2638
		if ((adapter->ecdev && ecdev_get_link(adapter->ecdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2639
				|| (!adapter->ecdev && netif_carrier_ok(netdev))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2640
			adapter->link_speed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2641
			adapter->link_duplex = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2642
			printk(KERN_INFO "e1000: %s NIC Link is Down\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2643
			       netdev->name);
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  2644
			if (adapter->ecdev) {
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2645
				ecdev_set_link(adapter->ecdev, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2646
			} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2647
				netif_carrier_off(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2648
				netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2649
				mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2650
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2651
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2652
			/* 80003ES2LAN workaround--
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2653
			 * For packet buffer work-around on link down event;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2654
			 * disable receives in the ISR and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2655
			 * reset device here in the watchdog
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2656
			 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2657
			if (hw->mac_type == e1000_80003es2lan)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2658
				/* reset device */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2659
				schedule_work(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2660
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2661
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2662
		e1000_smartspeed(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2663
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2664
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2665
	e1000_update_stats(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2666
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2667
	hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2668
	adapter->tpt_old = adapter->stats.tpt;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2669
	hw->collision_delta = adapter->stats.colc - adapter->colc_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2670
	adapter->colc_old = adapter->stats.colc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2671
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2672
	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2673
	adapter->gorcl_old = adapter->stats.gorcl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2674
	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2675
	adapter->gotcl_old = adapter->stats.gotcl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2676
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2677
	e1000_update_adaptive(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2678
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2679
	if (!adapter->ecdev && !netif_carrier_ok(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2680
		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2681
			/* We've lost link, so the controller stops DMA,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2682
			 * but we've got queued Tx work that's never going
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2683
			 * to get done, so reset controller to flush Tx.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2684
			 * (Do the reset outside of interrupt context). */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2685
			adapter->tx_timeout_count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2686
			schedule_work(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2687
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2688
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2689
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2690
	/* Cause software interrupt to ensure rx ring is cleaned */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2691
	ew32(ICS, E1000_ICS_RXDMT0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2692
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2693
	/* Force detection of hung controller every watchdog period */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2694
	if (!adapter->ecdev) adapter->detect_tx_hung = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2695
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2696
	/* With 82571 controllers, LAA may be overwritten due to controller
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2697
	 * reset from the other port. Set the appropriate LAA in RAR[0] */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2698
	if (hw->mac_type == e1000_82571 && hw->laa_is_present)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2699
		e1000_rar_set(hw, hw->mac_addr, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2700
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2701
	/* Reset the timer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2702
	if (!adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2703
		mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2704
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2705
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2706
enum latency_range {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2707
	lowest_latency = 0,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2708
	low_latency = 1,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2709
	bulk_latency = 2,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2710
	latency_invalid = 255
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2711
};
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2712
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2713
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2714
 * e1000_update_itr - update the dynamic ITR value based on statistics
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2715
 *      Stores a new ITR value based on packets and byte
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2716
 *      counts during the last interrupt.  The advantage of per interrupt
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2717
 *      computation is faster updates and more accurate ITR for the current
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2718
 *      traffic pattern.  Constants in this function were computed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2719
 *      based on theoretical maximum wire speed and thresholds were set based
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2720
 *      on testing data as well as attempting to minimize response time
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2721
 *      while increasing bulk throughput.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2722
 *      this functionality is controlled by the InterruptThrottleRate module
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2723
 *      parameter (see e1000_param.c)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2724
 * @adapter: pointer to adapter
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2725
 * @itr_setting: current adapter->itr
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2726
 * @packets: the number of packets during this measurement interval
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2727
 * @bytes: the number of bytes during this measurement interval
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2728
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2729
static unsigned int e1000_update_itr(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2730
				     u16 itr_setting, int packets, int bytes)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2731
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2732
	unsigned int retval = itr_setting;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2733
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2734
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2735
	if (unlikely(hw->mac_type < e1000_82540))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2736
		goto update_itr_done;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2737
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2738
	if (packets == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2739
		goto update_itr_done;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2740
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2741
	switch (itr_setting) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2742
	case lowest_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2743
		/* jumbo frames get bulk treatment*/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2744
		if (bytes/packets > 8000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2745
			retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2746
		else if ((packets < 5) && (bytes > 512))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2747
			retval = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2748
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2749
	case low_latency:  /* 50 usec aka 20000 ints/s */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2750
		if (bytes > 10000) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2751
			/* jumbo frames need bulk latency setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2752
			if (bytes/packets > 8000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2753
				retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2754
			else if ((packets < 10) || ((bytes/packets) > 1200))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2755
				retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2756
			else if ((packets > 35))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2757
				retval = lowest_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2758
		} else if (bytes/packets > 2000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2759
			retval = bulk_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2760
		else if (packets <= 2 && bytes < 512)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2761
			retval = lowest_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2762
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2763
	case bulk_latency: /* 250 usec aka 4000 ints/s */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2764
		if (bytes > 25000) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2765
			if (packets > 35)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2766
				retval = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2767
		} else if (bytes < 6000) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2768
			retval = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2769
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2770
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2771
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2772
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2773
update_itr_done:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2774
	return retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2775
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2776
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2777
static void e1000_set_itr(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2778
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2779
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2780
	u16 current_itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2781
	u32 new_itr = adapter->itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2782
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2783
	if (unlikely(hw->mac_type < e1000_82540))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2784
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2785
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2786
	/* for non-gigabit speeds, just fix the interrupt rate at 4000 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2787
	if (unlikely(adapter->link_speed != SPEED_1000)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2788
		current_itr = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2789
		new_itr = 4000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2790
		goto set_itr_now;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2791
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2792
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2793
	adapter->tx_itr = e1000_update_itr(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2794
	                            adapter->tx_itr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2795
	                            adapter->total_tx_packets,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2796
	                            adapter->total_tx_bytes);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2797
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2798
	if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2799
		adapter->tx_itr = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2800
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2801
	adapter->rx_itr = e1000_update_itr(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2802
	                            adapter->rx_itr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2803
	                            adapter->total_rx_packets,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2804
	                            adapter->total_rx_bytes);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2805
	/* conservative mode (itr 3) eliminates the lowest_latency setting */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2806
	if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2807
		adapter->rx_itr = low_latency;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2808
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2809
	current_itr = max(adapter->rx_itr, adapter->tx_itr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2810
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2811
	switch (current_itr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2812
	/* counts and packets in update_itr are dependent on these numbers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2813
	case lowest_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2814
		new_itr = 70000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2815
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2816
	case low_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2817
		new_itr = 20000; /* aka hwitr = ~200 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2818
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2819
	case bulk_latency:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2820
		new_itr = 4000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2821
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2822
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2823
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2824
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2825
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2826
set_itr_now:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2827
	if (new_itr != adapter->itr) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2828
		/* this attempts to bias the interrupt rate towards Bulk
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2829
		 * by adding intermediate steps when interrupt rate is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2830
		 * increasing */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2831
		new_itr = new_itr > adapter->itr ?
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2832
		             min(adapter->itr + (new_itr >> 2), new_itr) :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2833
		             new_itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2834
		adapter->itr = new_itr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2835
		ew32(ITR, 1000000000 / (new_itr * 256));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2836
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2837
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2838
	return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2839
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2840
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2841
#define E1000_TX_FLAGS_CSUM		0x00000001
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2842
#define E1000_TX_FLAGS_VLAN		0x00000002
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2843
#define E1000_TX_FLAGS_TSO		0x00000004
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2844
#define E1000_TX_FLAGS_IPV4		0x00000008
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2845
#define E1000_TX_FLAGS_VLAN_MASK	0xffff0000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2846
#define E1000_TX_FLAGS_VLAN_SHIFT	16
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2847
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2848
static int e1000_tso(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2849
		     struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2850
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2851
	struct e1000_context_desc *context_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2852
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2853
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2854
	u32 cmd_length = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2855
	u16 ipcse = 0, tucse, mss;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2856
	u8 ipcss, ipcso, tucss, tucso, hdr_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2857
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2858
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2859
	if (skb_is_gso(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2860
		if (skb_header_cloned(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2861
			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2862
			if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2863
				return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2864
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2865
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2866
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2867
		mss = skb_shinfo(skb)->gso_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2868
		if (skb->protocol == htons(ETH_P_IP)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2869
			struct iphdr *iph = ip_hdr(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2870
			iph->tot_len = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2871
			iph->check = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2872
			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2873
								 iph->daddr, 0,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2874
								 IPPROTO_TCP,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2875
								 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2876
			cmd_length = E1000_TXD_CMD_IP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2877
			ipcse = skb_transport_offset(skb) - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2878
		} else if (skb->protocol == htons(ETH_P_IPV6)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2879
			ipv6_hdr(skb)->payload_len = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2880
			tcp_hdr(skb)->check =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2881
				~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2882
						 &ipv6_hdr(skb)->daddr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2883
						 0, IPPROTO_TCP, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2884
			ipcse = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2885
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2886
		ipcss = skb_network_offset(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2887
		ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2888
		tucss = skb_transport_offset(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2889
		tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2890
		tucse = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2891
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2892
		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2893
			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2894
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2895
		i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2896
		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2897
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2898
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2899
		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2900
		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2901
		context_desc->lower_setup.ip_fields.ipcse  = cpu_to_le16(ipcse);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2902
		context_desc->upper_setup.tcp_fields.tucss = tucss;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2903
		context_desc->upper_setup.tcp_fields.tucso = tucso;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2904
		context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2905
		context_desc->tcp_seg_setup.fields.mss     = cpu_to_le16(mss);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2906
		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2907
		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2908
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2909
		buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2910
		buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2911
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2912
		if (++i == tx_ring->count) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2913
		tx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2914
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2915
		return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2916
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2917
	return false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2918
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2919
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2920
static bool e1000_tx_csum(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2921
			  struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2922
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2923
	struct e1000_context_desc *context_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2924
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2925
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2926
	u8 css;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2927
	u32 cmd_len = E1000_TXD_CMD_DEXT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2928
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2929
	if (skb->ip_summed != CHECKSUM_PARTIAL)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2930
		return false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2931
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2932
	switch (skb->protocol) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2933
	case __constant_htons(ETH_P_IP):
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2934
		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2935
			cmd_len |= E1000_TXD_CMD_TCP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2936
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2937
	case __constant_htons(ETH_P_IPV6):
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2938
		/* XXX not handling all IPV6 headers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2939
		if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2940
			cmd_len |= E1000_TXD_CMD_TCP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2941
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2942
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2943
		if (unlikely(net_ratelimit()))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2944
			DPRINTK(DRV, WARNING,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2945
			        "checksum_partial proto=%x!\n", skb->protocol);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2946
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2947
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2948
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2949
	css = skb_transport_offset(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2950
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2951
	i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2952
	buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2953
	context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2954
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2955
	context_desc->lower_setup.ip_config = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2956
	context_desc->upper_setup.tcp_fields.tucss = css;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2957
	context_desc->upper_setup.tcp_fields.tucso =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2958
		css + skb->csum_offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2959
	context_desc->upper_setup.tcp_fields.tucse = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2960
	context_desc->tcp_seg_setup.data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2961
	context_desc->cmd_and_length = cpu_to_le32(cmd_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2962
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2963
	buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2964
	buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2965
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2966
	if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2967
	tx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2968
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2969
	return true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2970
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2971
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2972
#define E1000_MAX_TXD_PWR	12
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2973
#define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2974
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2975
static int e1000_tx_map(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2976
			struct e1000_tx_ring *tx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2977
			struct sk_buff *skb, unsigned int first,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2978
			unsigned int max_per_txd, unsigned int nr_frags,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2979
			unsigned int mss)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2980
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2981
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2982
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2983
	unsigned int len = skb->len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2984
	unsigned int offset = 0, size, count = 0, i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2985
	unsigned int f;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2986
	len -= skb->data_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2987
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2988
	i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2989
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2990
	while (len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2991
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2992
		size = min(len, max_per_txd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2993
		/* Workaround for Controller erratum --
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2994
		 * descriptor for non-tso packet in a linear SKB that follows a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2995
		 * tso gets written back prematurely before the data is fully
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2996
		 * DMA'd to the controller */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2997
		if (!skb->data_len && tx_ring->last_tx_tso &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2998
		    !skb_is_gso(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  2999
			tx_ring->last_tx_tso = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3000
			size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3001
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3002
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3003
		/* Workaround for premature desc write-backs
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3004
		 * in TSO mode.  Append 4-byte sentinel desc */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3005
		if (unlikely(mss && !nr_frags && size == len && size > 8))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3006
			size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3007
		/* work-around for errata 10 and it applies
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3008
		 * to all controllers in PCI-X mode
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3009
		 * The fix is to make sure that the first descriptor of a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3010
		 * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3011
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3012
		if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3013
		                (size > 2015) && count == 0))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3014
		        size = 2015;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3015
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3016
		/* Workaround for potential 82544 hang in PCI-X.  Avoid
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3017
		 * terminating buffers within evenly-aligned dwords. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3018
		if (unlikely(adapter->pcix_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3019
		   !((unsigned long)(skb->data + offset + size - 1) & 4) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3020
		   size > 4))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3021
			size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3022
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3023
		buffer_info->length = size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3024
		buffer_info->dma =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3025
			pci_map_single(adapter->pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3026
				skb->data + offset,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3027
				size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3028
				PCI_DMA_TODEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3029
		buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3030
		buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3031
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3032
		len -= size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3033
		offset += size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3034
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3035
		if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3036
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3037
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3038
	for (f = 0; f < nr_frags; f++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3039
		struct skb_frag_struct *frag;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3040
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3041
		frag = &skb_shinfo(skb)->frags[f];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3042
		len = frag->size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3043
		offset = frag->page_offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3044
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3045
		while (len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3046
			buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3047
			size = min(len, max_per_txd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3048
			/* Workaround for premature desc write-backs
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3049
			 * in TSO mode.  Append 4-byte sentinel desc */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3050
			if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3051
				size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3052
			/* Workaround for potential 82544 hang in PCI-X.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3053
			 * Avoid terminating buffers within evenly-aligned
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3054
			 * dwords. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3055
			if (unlikely(adapter->pcix_82544 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3056
			   !((unsigned long)(frag->page+offset+size-1) & 4) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3057
			   size > 4))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3058
				size -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3059
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3060
			buffer_info->length = size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3061
			buffer_info->dma =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3062
				pci_map_page(adapter->pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3063
					frag->page,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3064
					offset,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3065
					size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3066
					PCI_DMA_TODEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3067
			buffer_info->time_stamp = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3068
			buffer_info->next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3069
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3070
			len -= size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3071
			offset += size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3072
			count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3073
			if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3074
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3075
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3076
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3077
	i = (i == 0) ? tx_ring->count - 1 : i - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3078
	tx_ring->buffer_info[i].skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3079
	tx_ring->buffer_info[first].next_to_watch = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3080
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3081
	return count;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3082
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3083
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3084
static void e1000_tx_queue(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3085
			   struct e1000_tx_ring *tx_ring, int tx_flags,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3086
			   int count)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3087
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3088
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3089
	struct e1000_tx_desc *tx_desc = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3090
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3091
	u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3092
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3093
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3094
	if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3095
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3096
		             E1000_TXD_CMD_TSE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3097
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3098
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3099
		if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3100
			txd_upper |= E1000_TXD_POPTS_IXSM << 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3101
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3102
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3103
	if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3104
		txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3105
		txd_upper |= E1000_TXD_POPTS_TXSM << 8;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3106
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3107
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3108
	if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3109
		txd_lower |= E1000_TXD_CMD_VLE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3110
		txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3111
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3112
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3113
	i = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3114
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3115
	while (count--) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3116
		buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3117
		tx_desc = E1000_TX_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3118
		tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3119
		tx_desc->lower.data =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3120
			cpu_to_le32(txd_lower | buffer_info->length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3121
		tx_desc->upper.data = cpu_to_le32(txd_upper);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3122
		if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3123
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3124
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3125
	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3126
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3127
	/* Force memory writes to complete before letting h/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3128
	 * know there are new descriptors to fetch.  (Only
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3129
	 * applicable for weak-ordered memory model archs,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3130
	 * such as IA-64). */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3131
	wmb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3132
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3133
	tx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3134
	writel(i, hw->hw_addr + tx_ring->tdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3135
	/* we need this if more than one processor can write to our tail
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3136
	 * at a time, it syncronizes IO on IA64/Altix systems */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3137
	mmiowb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3138
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3139
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3140
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3141
 * 82547 workaround to avoid controller hang in half-duplex environment.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3142
 * The workaround is to avoid queuing a large packet that would span
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3143
 * the internal Tx FIFO ring boundary by notifying the stack to resend
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3144
 * the packet at a later time.  This gives the Tx FIFO an opportunity to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3145
 * flush all packets.  When that occurs, we reset the Tx FIFO pointers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3146
 * to the beginning of the Tx FIFO.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3147
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3148
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3149
#define E1000_FIFO_HDR			0x10
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3150
#define E1000_82547_PAD_LEN		0x3E0
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3151
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3152
static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3153
				       struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3154
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3155
	u32 fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3156
	u32 skb_fifo_len = skb->len + E1000_FIFO_HDR;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3157
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3158
	skb_fifo_len = ALIGN(skb_fifo_len, E1000_FIFO_HDR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3159
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3160
	if (adapter->link_duplex != HALF_DUPLEX)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3161
		goto no_fifo_stall_required;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3162
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3163
	if (atomic_read(&adapter->tx_fifo_stall))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3164
		return 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3165
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3166
	if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3167
		atomic_set(&adapter->tx_fifo_stall, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3168
		return 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3169
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3170
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3171
no_fifo_stall_required:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3172
	adapter->tx_fifo_head += skb_fifo_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3173
	if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3174
		adapter->tx_fifo_head -= adapter->tx_fifo_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3175
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3176
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3177
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3178
#define MINIMUM_DHCP_PACKET_SIZE 282
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3179
static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3180
				    struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3181
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3182
	struct e1000_hw *hw =  &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3183
	u16 length, offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3184
	if (vlan_tx_tag_present(skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3185
		if (!((vlan_tx_tag_get(skb) == hw->mng_cookie.vlan_id) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3186
			( hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3187
			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3188
			return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3189
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3190
	if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3191
		struct ethhdr *eth = (struct ethhdr *)skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3192
		if ((htons(ETH_P_IP) == eth->h_proto)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3193
			const struct iphdr *ip =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3194
				(struct iphdr *)((u8 *)skb->data+14);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3195
			if (IPPROTO_UDP == ip->protocol) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3196
				struct udphdr *udp =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3197
					(struct udphdr *)((u8 *)ip +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3198
						(ip->ihl << 2));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3199
				if (ntohs(udp->dest) == 67) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3200
					offset = (u8 *)udp + 8 - skb->data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3201
					length = skb->len - offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3202
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3203
					return e1000_mng_write_dhcp_info(hw,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3204
							(u8 *)udp + 8,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3205
							length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3206
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3207
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3208
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3209
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3210
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3211
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3212
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3213
static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3214
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3215
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3216
	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3217
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3218
	if (adapter->ecdev) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3219
		return -EBUSY;
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3220
	}
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3221
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3222
	netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3223
	/* Herbert's original patch had:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3224
	 *  smp_mb__after_netif_stop_queue();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3225
	 * but since that doesn't exist yet, just open code it. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3226
	smp_mb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3227
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3228
	/* We need to check again in a case another CPU has just
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3229
	 * made room available. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3230
	if (likely(E1000_DESC_UNUSED(tx_ring) < size))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3231
		return -EBUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3232
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3233
	/* A reprieve! */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3234
	netif_start_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3235
	++adapter->restart_queue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3236
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3237
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3238
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3239
static int e1000_maybe_stop_tx(struct net_device *netdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3240
                               struct e1000_tx_ring *tx_ring, int size)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3241
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3242
	if (likely(E1000_DESC_UNUSED(tx_ring) >= size))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3243
		return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3244
	return __e1000_maybe_stop_tx(netdev, size);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3245
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3246
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3247
#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3248
static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3249
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3250
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3251
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3252
	struct e1000_tx_ring *tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3253
	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3254
	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3255
	unsigned int tx_flags = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3256
	unsigned int len = skb->len - skb->data_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3257
	unsigned long flags = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3258
	unsigned int nr_frags = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3259
	unsigned int mss = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3260
	int count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3261
	int tso;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3262
	unsigned int f;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3263
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3264
	/* This goes back to the question of how to logically map a tx queue
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3265
	 * to a flow.  Right now, performance is impacted slightly negatively
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3266
	 * if using multiple tx queues.  If the stack breaks away from a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3267
	 * single qdisc implementation, we can look at this again. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3268
	tx_ring = adapter->tx_ring;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3269
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3270
	if (unlikely(skb->len <= 0)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3271
		if (!adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3272
			dev_kfree_skb_any(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3273
		return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3274
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3275
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3276
	/* 82571 and newer doesn't need the workaround that limited descriptor
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3277
	 * length to 4kB */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3278
	if (hw->mac_type >= e1000_82571)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3279
		max_per_txd = 8192;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3280
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3281
	mss = skb_shinfo(skb)->gso_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3282
	/* The controller does a simple calculation to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3283
	 * make sure there is enough room in the FIFO before
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3284
	 * initiating the DMA for each buffer.  The calc is:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3285
	 * 4 = ceil(buffer len/mss).  To make sure we don't
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3286
	 * overrun the FIFO, adjust the max buffer len if mss
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3287
	 * drops. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3288
	if (mss) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3289
		u8 hdr_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3290
		max_per_txd = min(mss << 2, max_per_txd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3291
		max_txd_pwr = fls(max_per_txd) - 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3292
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3293
		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3294
		* points to just header, pull a few bytes of payload from
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3295
		* frags into skb->data */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3296
		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3297
		if (skb->data_len && hdr_len == len) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3298
			switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3299
				unsigned int pull_size;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3300
			case e1000_82544:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3301
				/* Make sure we have room to chop off 4 bytes,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3302
				 * and that the end alignment will work out to
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3303
				 * this hardware's requirements
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3304
				 * NOTE: this is a TSO only workaround
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3305
				 * if end byte alignment not correct move us
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3306
				 * into the next dword */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3307
				if ((unsigned long)(skb_tail_pointer(skb) - 1) & 4)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3308
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3309
				/* fall through */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3310
			case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3311
			case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3312
			case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3313
			case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3314
				pull_size = min((unsigned int)4, skb->data_len);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3315
				if (!__pskb_pull_tail(skb, pull_size)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3316
					DPRINTK(DRV, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3317
						"__pskb_pull_tail failed.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3318
					dev_kfree_skb_any(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3319
					return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3320
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3321
				len = skb->len - skb->data_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3322
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3323
			default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3324
				/* do nothing */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3325
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3326
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3327
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3328
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3329
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3330
	/* reserve a descriptor for the offload context */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3331
	if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3332
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3333
	count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3334
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3335
	/* Controller Erratum workaround */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3336
	if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3337
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3338
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3339
	count += TXD_USE_COUNT(len, max_txd_pwr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3340
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3341
	if (adapter->pcix_82544)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3342
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3343
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3344
	/* work-around for errata 10 and it applies to all controllers
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3345
	 * in PCI-X mode, so add one more descriptor to the count
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3346
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3347
	if (unlikely((hw->bus_type == e1000_bus_type_pcix) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3348
			(len > 2015)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3349
		count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3350
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3351
	nr_frags = skb_shinfo(skb)->nr_frags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3352
	for (f = 0; f < nr_frags; f++)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3353
		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3354
				       max_txd_pwr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3355
	if (adapter->pcix_82544)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3356
		count += nr_frags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3357
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3358
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3359
	if (hw->tx_pkt_filtering &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3360
	    (hw->mac_type == e1000_82573))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3361
		e1000_transfer_dhcp_info(adapter, skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3362
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3363
	if (!adapter->ecdev &&
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3364
			!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3365
		/* Collision - tell upper layer to requeue */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3366
		return NETDEV_TX_LOCKED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3367
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3368
	/* need: count + 2 desc gap to keep tail from touching
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3369
	 * head, otherwise try next time */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3370
	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3371
		if (!adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3372
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3373
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3374
		return NETDEV_TX_BUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3375
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3376
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3377
	if (unlikely(hw->mac_type == e1000_82547)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3378
		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3379
			if (!adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3380
				netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3381
				mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3382
				spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3383
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3384
			return NETDEV_TX_BUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3385
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3386
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3387
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3388
	if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3389
		tx_flags |= E1000_TX_FLAGS_VLAN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3390
		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3391
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3392
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3393
	first = tx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3394
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3395
	tso = e1000_tso(adapter, tx_ring, skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3396
	if (tso < 0) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3397
		if (!adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3398
			dev_kfree_skb_any(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3399
			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3400
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3401
		return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3402
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3403
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3404
	if (likely(tso)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3405
		tx_ring->last_tx_tso = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3406
		tx_flags |= E1000_TX_FLAGS_TSO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3407
	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3408
		tx_flags |= E1000_TX_FLAGS_CSUM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3409
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3410
	/* Old method was to assume IPv4 packet by default if TSO was enabled.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3411
	 * 82571 hardware supports TSO capabilities for IPv6 as well...
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3412
	 * no longer assume, we must. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3413
	if (likely(skb->protocol == htons(ETH_P_IP)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3414
		tx_flags |= E1000_TX_FLAGS_IPV4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3415
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3416
	e1000_tx_queue(adapter, tx_ring, tx_flags,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3417
	               e1000_tx_map(adapter, tx_ring, skb, first,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3418
	                            max_per_txd, nr_frags, mss));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3419
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3420
	netdev->trans_start = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3421
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3422
	if (!adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3423
		/* Make sure there is space in the ring for the next send. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3424
		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3425
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3426
		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3427
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3428
	return NETDEV_TX_OK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3429
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3430
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3431
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3432
 * e1000_tx_timeout - Respond to a Tx Hang
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3433
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3434
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3435
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3436
static void e1000_tx_timeout(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3437
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3438
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3439
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3440
	/* Do the reset outside of interrupt context */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3441
	adapter->tx_timeout_count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3442
	schedule_work(&adapter->reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3443
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3444
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3445
static void e1000_reset_task(struct work_struct *work)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3446
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3447
	struct e1000_adapter *adapter =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3448
		container_of(work, struct e1000_adapter, reset_task);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3449
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3450
	e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3451
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3452
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3453
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3454
 * e1000_get_stats - Get System Network Statistics
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3455
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3456
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3457
 * Returns the address of the device statistics structure.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3458
 * The statistics are actually updated from the timer callback.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3459
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3460
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3461
static struct net_device_stats *e1000_get_stats(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3462
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3463
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3464
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3465
	/* only return the current stats */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3466
	return &adapter->net_stats;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3467
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3468
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3469
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3470
 * e1000_change_mtu - Change the Maximum Transfer Unit
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3471
 * @netdev: network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3472
 * @new_mtu: new value for maximum frame size
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3473
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3474
 * Returns 0 on success, negative on failure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3475
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3476
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3477
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3478
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3479
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3480
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3481
	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3482
	u16 eeprom_data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3483
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3484
	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3485
		return -EBUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3486
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3487
	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3488
	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3489
		DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3490
		return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3491
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3492
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3493
	/* Adapter-specific max frame size limits. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3494
	switch (hw->mac_type) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3495
	case e1000_undefined ... e1000_82542_rev2_1:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3496
	case e1000_ich8lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3497
		if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3498
			DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3499
			return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3500
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3501
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3502
	case e1000_82573:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3503
		/* Jumbo Frames not supported if:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3504
		 * - this is not an 82573L device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3505
		 * - ASPM is enabled in any way (0x1A bits 3:2) */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3506
		e1000_read_eeprom(hw, EEPROM_INIT_3GIO_3, 1,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3507
		                  &eeprom_data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3508
		if ((hw->device_id != E1000_DEV_ID_82573L) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3509
		    (eeprom_data & EEPROM_WORD1A_ASPM_MASK)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3510
			if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3511
				DPRINTK(PROBE, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3512
			            	"Jumbo Frames not supported.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3513
				return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3514
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3515
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3516
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3517
		/* ERT will be enabled later to enable wire speed receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3518
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3519
		/* fall through to get support */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3520
	case e1000_82571:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3521
	case e1000_82572:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3522
	case e1000_80003es2lan:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3523
#define MAX_STD_JUMBO_FRAME_SIZE 9234
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3524
		if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3525
			DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3526
			return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3527
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3528
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3529
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3530
		/* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3531
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3532
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3533
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3534
	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3535
	 * means we reserve 2 more, this pushes us to allocate from the next
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3536
	 * larger slab size
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3537
	 * i.e. RXBUFFER_2048 --> size-4096 slab */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3538
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3539
	if (max_frame <= E1000_RXBUFFER_256)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3540
		adapter->rx_buffer_len = E1000_RXBUFFER_256;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3541
	else if (max_frame <= E1000_RXBUFFER_512)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3542
		adapter->rx_buffer_len = E1000_RXBUFFER_512;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3543
	else if (max_frame <= E1000_RXBUFFER_1024)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3544
		adapter->rx_buffer_len = E1000_RXBUFFER_1024;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3545
	else if (max_frame <= E1000_RXBUFFER_2048)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3546
		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3547
	else if (max_frame <= E1000_RXBUFFER_4096)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3548
		adapter->rx_buffer_len = E1000_RXBUFFER_4096;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3549
	else if (max_frame <= E1000_RXBUFFER_8192)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3550
		adapter->rx_buffer_len = E1000_RXBUFFER_8192;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3551
	else if (max_frame <= E1000_RXBUFFER_16384)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3552
		adapter->rx_buffer_len = E1000_RXBUFFER_16384;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3553
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3554
	/* adjust allocation if LPE protects us, and we aren't using SBP */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3555
	if (!hw->tbi_compatibility_on &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3556
	    ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3557
	     (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3558
		adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3559
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3560
	netdev->mtu = new_mtu;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3561
	hw->max_frame_size = max_frame;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3562
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3563
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3564
		e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3565
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3566
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3567
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3568
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3569
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3570
 * e1000_update_stats - Update the board statistics counters
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3571
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3572
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3573
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3574
void e1000_update_stats(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3575
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3576
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3577
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3578
	unsigned long flags = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3579
	u16 phy_tmp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3580
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3581
#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3582
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3583
	/*
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3584
	 * Prevent stats update while adapter is being reset, or if the pci
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3585
	 * connection is down.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3586
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3587
	if (adapter->link_speed == 0)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3588
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3589
	if (pci_channel_offline(pdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3590
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3591
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3592
	if (!adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3593
		spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3594
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3595
	/* these counters are modified from e1000_tbi_adjust_stats,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3596
	 * called from the interrupt context, so they must only
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3597
	 * be written while holding adapter->stats_lock
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3598
	 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3599
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3600
	adapter->stats.crcerrs += er32(CRCERRS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3601
	adapter->stats.gprc += er32(GPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3602
	adapter->stats.gorcl += er32(GORCL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3603
	adapter->stats.gorch += er32(GORCH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3604
	adapter->stats.bprc += er32(BPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3605
	adapter->stats.mprc += er32(MPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3606
	adapter->stats.roc += er32(ROC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3607
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3608
	if (hw->mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3609
		adapter->stats.prc64 += er32(PRC64);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3610
		adapter->stats.prc127 += er32(PRC127);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3611
		adapter->stats.prc255 += er32(PRC255);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3612
		adapter->stats.prc511 += er32(PRC511);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3613
		adapter->stats.prc1023 += er32(PRC1023);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3614
		adapter->stats.prc1522 += er32(PRC1522);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3615
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3616
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3617
	adapter->stats.symerrs += er32(SYMERRS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3618
	adapter->stats.mpc += er32(MPC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3619
	adapter->stats.scc += er32(SCC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3620
	adapter->stats.ecol += er32(ECOL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3621
	adapter->stats.mcc += er32(MCC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3622
	adapter->stats.latecol += er32(LATECOL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3623
	adapter->stats.dc += er32(DC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3624
	adapter->stats.sec += er32(SEC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3625
	adapter->stats.rlec += er32(RLEC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3626
	adapter->stats.xonrxc += er32(XONRXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3627
	adapter->stats.xontxc += er32(XONTXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3628
	adapter->stats.xoffrxc += er32(XOFFRXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3629
	adapter->stats.xofftxc += er32(XOFFTXC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3630
	adapter->stats.fcruc += er32(FCRUC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3631
	adapter->stats.gptc += er32(GPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3632
	adapter->stats.gotcl += er32(GOTCL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3633
	adapter->stats.gotch += er32(GOTCH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3634
	adapter->stats.rnbc += er32(RNBC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3635
	adapter->stats.ruc += er32(RUC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3636
	adapter->stats.rfc += er32(RFC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3637
	adapter->stats.rjc += er32(RJC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3638
	adapter->stats.torl += er32(TORL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3639
	adapter->stats.torh += er32(TORH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3640
	adapter->stats.totl += er32(TOTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3641
	adapter->stats.toth += er32(TOTH);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3642
	adapter->stats.tpr += er32(TPR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3643
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3644
	if (hw->mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3645
		adapter->stats.ptc64 += er32(PTC64);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3646
		adapter->stats.ptc127 += er32(PTC127);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3647
		adapter->stats.ptc255 += er32(PTC255);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3648
		adapter->stats.ptc511 += er32(PTC511);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3649
		adapter->stats.ptc1023 += er32(PTC1023);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3650
		adapter->stats.ptc1522 += er32(PTC1522);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3651
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3652
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3653
	adapter->stats.mptc += er32(MPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3654
	adapter->stats.bptc += er32(BPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3655
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3656
	/* used for adaptive IFS */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3657
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3658
	hw->tx_packet_delta = er32(TPT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3659
	adapter->stats.tpt += hw->tx_packet_delta;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3660
	hw->collision_delta = er32(COLC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3661
	adapter->stats.colc += hw->collision_delta;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3662
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3663
	if (hw->mac_type >= e1000_82543) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3664
		adapter->stats.algnerrc += er32(ALGNERRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3665
		adapter->stats.rxerrc += er32(RXERRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3666
		adapter->stats.tncrs += er32(TNCRS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3667
		adapter->stats.cexterr += er32(CEXTERR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3668
		adapter->stats.tsctc += er32(TSCTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3669
		adapter->stats.tsctfc += er32(TSCTFC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3670
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3671
	if (hw->mac_type > e1000_82547_rev_2) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3672
		adapter->stats.iac += er32(IAC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3673
		adapter->stats.icrxoc += er32(ICRXOC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3674
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3675
		if (hw->mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3676
			adapter->stats.icrxptc += er32(ICRXPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3677
			adapter->stats.icrxatc += er32(ICRXATC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3678
			adapter->stats.ictxptc += er32(ICTXPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3679
			adapter->stats.ictxatc += er32(ICTXATC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3680
			adapter->stats.ictxqec += er32(ICTXQEC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3681
			adapter->stats.ictxqmtc += er32(ICTXQMTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3682
			adapter->stats.icrxdmtc += er32(ICRXDMTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3683
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3684
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3685
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3686
	/* Fill out the OS statistics structure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3687
	adapter->net_stats.multicast = adapter->stats.mprc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3688
	adapter->net_stats.collisions = adapter->stats.colc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3689
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3690
	/* Rx Errors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3691
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3692
	/* RLEC on some newer hardware can be incorrect so build
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3693
	* our own version based on RUC and ROC */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3694
	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3695
		adapter->stats.crcerrs + adapter->stats.algnerrc +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3696
		adapter->stats.ruc + adapter->stats.roc +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3697
		adapter->stats.cexterr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3698
	adapter->stats.rlerrc = adapter->stats.ruc + adapter->stats.roc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3699
	adapter->net_stats.rx_length_errors = adapter->stats.rlerrc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3700
	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3701
	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3702
	adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3703
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3704
	/* Tx Errors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3705
	adapter->stats.txerrc = adapter->stats.ecol + adapter->stats.latecol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3706
	adapter->net_stats.tx_errors = adapter->stats.txerrc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3707
	adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3708
	adapter->net_stats.tx_window_errors = adapter->stats.latecol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3709
	adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3710
	if (hw->bad_tx_carr_stats_fd &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3711
	    adapter->link_duplex == FULL_DUPLEX) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3712
		adapter->net_stats.tx_carrier_errors = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3713
		adapter->stats.tncrs = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3714
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3715
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3716
	/* Tx Dropped needs to be maintained elsewhere */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3717
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3718
	/* Phy Stats */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3719
	if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3720
		if ((adapter->link_speed == SPEED_1000) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3721
		   (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3722
			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3723
			adapter->phy_stats.idle_errors += phy_tmp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3724
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3725
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3726
		if ((hw->mac_type <= e1000_82546) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3727
		   (hw->phy_type == e1000_phy_m88) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3728
		   !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3729
			adapter->phy_stats.receive_errors += phy_tmp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3730
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3731
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3732
	/* Management Stats */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3733
	if (hw->has_smbus) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3734
		adapter->stats.mgptc += er32(MGTPTC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3735
		adapter->stats.mgprc += er32(MGTPRC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3736
		adapter->stats.mgpdc += er32(MGTPDC);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3737
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3738
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3739
	if (!adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3740
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3741
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3742
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3743
void ec_poll(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3744
{
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3745
	struct e1000_adapter *adapter = netdev_priv(netdev);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3746
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3747
	if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3748
		e1000_watchdog((unsigned long) adapter);
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3749
		adapter->ec_watchdog_jiffies = jiffies;
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3750
	}
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3751
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3752
#ifdef CONFIG_PCI_MSI
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3753
	e1000_intr_msi(0, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3754
#else
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3755
	e1000_intr(0, netdev);
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3756
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3757
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3758
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3759
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3760
 * e1000_intr_msi - Interrupt Handler
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3761
 * @irq: interrupt number
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3762
 * @data: pointer to a network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3763
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3764
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3765
static irqreturn_t e1000_intr_msi(int irq, void *data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3766
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3767
	struct net_device *netdev = data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3768
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3769
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3770
	u32 icr = er32(ICR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3771
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3772
	if (adapter->ecdev) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3773
		int i, ec_work_done = 0;
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3774
		for (i = 0; i < E1000_MAX_INTR; i++) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3775
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3776
							&ec_work_done, 100) &&
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3777
						!e1000_clean_tx_irq(adapter, adapter->tx_ring))) {
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3778
				break;
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3779
			}
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3780
		}
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  3781
	} else {
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3782
		/* in NAPI mode read ICR disables interrupts using IAM */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3783
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3784
		if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3785
			hw->get_link_status = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3786
			/* 80003ES2LAN workaround-- For packet buffer work-around on
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3787
			 * link down event; disable receives here in the ISR and reset
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3788
			 * adapter in watchdog */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3789
			if (netif_carrier_ok(netdev) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3790
				(hw->mac_type == e1000_80003es2lan)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3791
				/* disable receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3792
				u32 rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3793
				ew32(RCTL, rctl & ~E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3794
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3795
			/* guard against interrupt when we're going down */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3796
			if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3797
				mod_timer(&adapter->watchdog_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3798
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3799
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3800
		if (likely(netif_rx_schedule_prep(&adapter->napi))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3801
			adapter->total_tx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3802
			adapter->total_tx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3803
			adapter->total_rx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3804
			adapter->total_rx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3805
			__netif_rx_schedule(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3806
		} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3807
			e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3808
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3809
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3810
	return IRQ_HANDLED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3811
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3812
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3813
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3814
 * e1000_intr - Interrupt Handler
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3815
 * @irq: interrupt number
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3816
 * @data: pointer to a network interface device structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3817
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3818
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3819
static irqreturn_t e1000_intr(int irq, void *data)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3820
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3821
	struct net_device *netdev = data;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3822
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3823
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3824
	u32 rctl, icr = er32(ICR);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3825
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3826
	if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3827
		return IRQ_NONE;  /* Not our interrupt */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3828
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3829
	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3830
	 * not set, then the adapter didn't send an interrupt */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3831
	if (unlikely(hw->mac_type >= e1000_82571 &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3832
	             !(icr & E1000_ICR_INT_ASSERTED)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3833
		return IRQ_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3834
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3835
	/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3836
	 * need for the IMC write */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3837
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3838
	if (!adapter->ecdev && unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3839
		hw->get_link_status = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3840
		/* 80003ES2LAN workaround--
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3841
		 * For packet buffer work-around on link down event;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3842
		 * disable receives here in the ISR and
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3843
		 * reset adapter in watchdog
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3844
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3845
		if (netif_carrier_ok(netdev) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3846
		    (hw->mac_type == e1000_80003es2lan)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3847
			/* disable receives */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3848
			rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3849
			ew32(RCTL, rctl & ~E1000_RCTL_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3850
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3851
		/* guard against interrupt when we're going down */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3852
		if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3853
			mod_timer(&adapter->watchdog_timer, jiffies + 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3854
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3855
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3856
	if (adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3857
		int i, ec_work_done = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3858
		for (i = 0; i < E1000_MAX_INTR; i++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3859
			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
2163
d6d49dcaf7a5 Fixed accidentially used operator & by using &&.
Florian Pose <fp@igh-essen.com>
parents: 2162
diff changeset
  3860
							&ec_work_done, 100) &&
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3861
						!e1000_clean_tx_irq(adapter, adapter->tx_ring))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3862
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3863
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3864
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3865
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3866
		if (unlikely(hw->mac_type < e1000_82571)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3867
			/* disable interrupts, without the synchronize_irq bit */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3868
			ew32(IMC, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3869
			E1000_WRITE_FLUSH();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3870
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3871
		if (likely(netif_rx_schedule_prep(&adapter->napi))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3872
			adapter->total_tx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3873
			adapter->total_tx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3874
			adapter->total_rx_bytes = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3875
			adapter->total_rx_packets = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3876
			__netif_rx_schedule(&adapter->napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3877
		} else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3878
			/* this really should not happen! if it does it is basically a
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3879
			 * bug, but not a hard error, so enable ints and continue */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3880
			e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3881
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3882
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3883
	return IRQ_HANDLED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3884
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3885
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3886
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3887
 * e1000_clean - NAPI Rx polling callback
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3888
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3889
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3890
static int e1000_clean(struct napi_struct *napi, int budget)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3891
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3892
	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3893
	struct net_device *poll_dev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3894
	int tx_cleaned = 0, work_done = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3895
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3896
	adapter = netdev_priv(poll_dev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3897
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3898
	/* e1000_clean is called per-cpu.  This lock protects
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3899
	 * tx_ring[0] from being cleaned by multiple cpus
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3900
	 * simultaneously.  A failure obtaining the lock means
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3901
	 * tx_ring[0] is currently being cleaned anyway. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3902
	if (spin_trylock(&adapter->tx_queue_lock)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3903
		tx_cleaned = e1000_clean_tx_irq(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3904
						&adapter->tx_ring[0]);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3905
		spin_unlock(&adapter->tx_queue_lock);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3906
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3907
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3908
	adapter->clean_rx(adapter, &adapter->rx_ring[0],
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3909
	                  &work_done, budget);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3910
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3911
	if (tx_cleaned)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3912
		work_done = budget;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3913
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3914
	/* If budget not fully consumed, exit the polling mode */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3915
	if (work_done < budget) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3916
		if (likely(adapter->itr_setting & 3))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3917
			e1000_set_itr(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3918
		netif_rx_complete(napi);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3919
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3920
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3921
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3922
	return work_done;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3923
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3924
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3925
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3926
 * e1000_clean_tx_irq - Reclaim resources after transmit completes
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3927
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3928
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3929
static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3930
			       struct e1000_tx_ring *tx_ring)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3931
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3932
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3933
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3934
	struct e1000_tx_desc *tx_desc, *eop_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3935
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3936
	unsigned int i, eop;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3937
	unsigned int count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3938
	bool cleaned = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3939
	unsigned int total_tx_bytes=0, total_tx_packets=0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3940
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3941
	i = tx_ring->next_to_clean;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3942
	eop = tx_ring->buffer_info[i].next_to_watch;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3943
	eop_desc = E1000_TX_DESC(*tx_ring, eop);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3944
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3945
	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3946
		for (cleaned = false; !cleaned; ) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3947
			tx_desc = E1000_TX_DESC(*tx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3948
			buffer_info = &tx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3949
			cleaned = (i == eop);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3950
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3951
			if (cleaned) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3952
				struct sk_buff *skb = buffer_info->skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3953
				unsigned int segs, bytecount;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3954
				segs = skb_shinfo(skb)->gso_segs ?: 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3955
				/* multiply data chunks by size of headers */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3956
				bytecount = ((segs - 1) * skb_headlen(skb)) +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3957
				            skb->len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3958
				total_tx_packets += segs;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3959
				total_tx_bytes += bytecount;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3960
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3961
			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3962
			tx_desc->upper.data = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3963
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3964
			if (unlikely(++i == tx_ring->count)) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3965
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3966
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3967
		eop = tx_ring->buffer_info[i].next_to_watch;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3968
		eop_desc = E1000_TX_DESC(*tx_ring, eop);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3969
#define E1000_TX_WEIGHT 64
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3970
		/* weight of a sort for tx, to avoid endless transmit cleanup */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3971
		if (count++ == E1000_TX_WEIGHT)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3972
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3973
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3974
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3975
	tx_ring->next_to_clean = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3976
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3977
#define TX_WAKE_THRESHOLD 32
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3978
	if (!adapter->ecdev && unlikely(cleaned && netif_carrier_ok(netdev) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3979
		     E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3980
		/* Make sure that anybody stopping the queue after this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3981
		 * sees the new next_to_clean.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3982
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3983
		smp_mb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3984
		if (netif_queue_stopped(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3985
			netif_wake_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3986
			++adapter->restart_queue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3987
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3988
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3989
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3990
	if (!adapter->ecdev && adapter->detect_tx_hung) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3991
		/* Detect a transmit hang in hardware, this serializes the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3992
		 * check with the clearing of time_stamp and movement of i */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3993
		adapter->detect_tx_hung = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3994
		if (tx_ring->buffer_info[eop].dma &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3995
		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3996
		               (adapter->tx_timeout_factor * HZ))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3997
		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3998
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  3999
			/* detected Tx unit hang */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4000
			DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4001
					"  Tx Queue             <%lu>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4002
					"  TDH                  <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4003
					"  TDT                  <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4004
					"  next_to_use          <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4005
					"  next_to_clean        <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4006
					"buffer_info[next_to_clean]\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4007
					"  time_stamp           <%lx>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4008
					"  next_to_watch        <%x>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4009
					"  jiffies              <%lx>\n"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4010
					"  next_to_watch.status <%x>\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4011
				(unsigned long)((tx_ring - adapter->tx_ring) /
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4012
					sizeof(struct e1000_tx_ring)),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4013
				readl(hw->hw_addr + tx_ring->tdh),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4014
				readl(hw->hw_addr + tx_ring->tdt),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4015
				tx_ring->next_to_use,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4016
				tx_ring->next_to_clean,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4017
				tx_ring->buffer_info[eop].time_stamp,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4018
				eop,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4019
				jiffies,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4020
				eop_desc->upper.fields.status);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4021
			netif_stop_queue(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4022
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4023
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4024
	adapter->total_tx_bytes += total_tx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4025
	adapter->total_tx_packets += total_tx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4026
	adapter->net_stats.tx_bytes += total_tx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4027
	adapter->net_stats.tx_packets += total_tx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4028
	return cleaned;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4029
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4030
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4031
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4032
 * e1000_rx_checksum - Receive Checksum Offload for 82543
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4033
 * @adapter:     board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4034
 * @status_err:  receive descriptor status and error fields
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4035
 * @csum:        receive descriptor csum field
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4036
 * @sk_buff:     socket buffer with received data
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4037
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4038
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4039
static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4040
			      u32 csum, struct sk_buff *skb)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4041
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4042
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4043
	u16 status = (u16)status_err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4044
	u8 errors = (u8)(status_err >> 24);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4045
	skb->ip_summed = CHECKSUM_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4046
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4047
	/* 82543 or newer only */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4048
	if (unlikely(hw->mac_type < e1000_82543)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4049
	/* Ignore Checksum bit is set */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4050
	if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4051
	/* TCP/UDP checksum error bit is set */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4052
	if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4053
		/* let the stack verify checksum errors */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4054
		adapter->hw_csum_err++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4055
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4056
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4057
	/* TCP/UDP Checksum has not been calculated */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4058
	if (hw->mac_type <= e1000_82547_rev_2) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4059
		if (!(status & E1000_RXD_STAT_TCPCS))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4060
			return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4061
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4062
		if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4063
			return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4064
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4065
	/* It must be a TCP or UDP packet with a valid checksum */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4066
	if (likely(status & E1000_RXD_STAT_TCPCS)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4067
		/* TCP checksum is good */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4068
		skb->ip_summed = CHECKSUM_UNNECESSARY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4069
	} else if (hw->mac_type > e1000_82547_rev_2) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4070
		/* IP fragment with UDP payload */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4071
		/* Hardware complements the payload checksum, so we undo it
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4072
		 * and then put the value in host order for further stack use.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4073
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4074
		__sum16 sum = (__force __sum16)htons(csum);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4075
		skb->csum = csum_unfold(~sum);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4076
		skb->ip_summed = CHECKSUM_COMPLETE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4077
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4078
	adapter->hw_csum_good++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4079
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4080
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4081
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4082
 * e1000_clean_rx_irq - Send received data up the network stack; legacy
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4083
 * @adapter: board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4084
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4085
static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4086
			       struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4087
			       int *work_done, int work_to_do)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4088
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4089
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4090
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4091
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4092
	struct e1000_rx_desc *rx_desc, *next_rxd;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4093
	struct e1000_buffer *buffer_info, *next_buffer;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4094
	unsigned long flags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4095
	u32 length;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4096
	u8 last_byte;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4097
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4098
	int cleaned_count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4099
	bool cleaned = false;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4100
	unsigned int total_rx_bytes=0, total_rx_packets=0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4101
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4102
	i = rx_ring->next_to_clean;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4103
	rx_desc = E1000_RX_DESC(*rx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4104
	buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4105
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4106
	while (rx_desc->status & E1000_RXD_STAT_DD) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4107
		struct sk_buff *skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4108
		u8 status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4109
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4110
		if (*work_done >= work_to_do)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4111
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4112
		(*work_done)++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4113
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4114
		status = rx_desc->status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4115
		skb = buffer_info->skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4116
		if (!adapter->ecdev) buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4117
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4118
		prefetch(skb->data - NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4119
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4120
		if (++i == rx_ring->count) i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4121
		next_rxd = E1000_RX_DESC(*rx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4122
		prefetch(next_rxd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4123
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4124
		next_buffer = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4125
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4126
		cleaned = true;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4127
		cleaned_count++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4128
		pci_unmap_single(pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4129
		                 buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4130
		                 buffer_info->length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4131
		                 PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4132
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4133
		length = le16_to_cpu(rx_desc->length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4134
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4135
		if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4136
			/* All receives must fit into a single buffer */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4137
			E1000_DBG("%s: Receive packet consumed multiple"
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4138
				  " buffers\n", netdev->name);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4139
			/* recycle */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4140
			buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4141
			goto next_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4142
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4143
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4144
		if (!adapter->ecdev &&
2589
2b9c78543663 Reverted default branch to stable-1.5.
Florian Pose <fp@igh-essen.com>
parents: 2163
diff changeset
  4145
				unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
2072
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4146
			last_byte = *(skb->data + length - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4147
			if (TBI_ACCEPT(hw, status, rx_desc->errors, length,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4148
				       last_byte)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4149
				spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4150
				e1000_tbi_adjust_stats(hw, &adapter->stats,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4151
				                       length, skb->data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4152
				spin_unlock_irqrestore(&adapter->stats_lock,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4153
				                       flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4154
				length--;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4155
			} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4156
				/* recycle */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4157
				buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4158
				goto next_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4159
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4160
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4161
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4162
		/* adjust length to remove Ethernet CRC, this must be
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4163
		 * done after the TBI_ACCEPT workaround above */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4164
		length -= 4;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4165
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4166
		/* probably a little skewed due to removing CRC */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4167
		total_rx_bytes += length;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4168
		total_rx_packets++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4169
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4170
		/* code added for copybreak, this should improve
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4171
		 * performance for small packets with large amounts
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4172
		 * of reassembly being done in the stack */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4173
		if (!adapter->ecdev && length < copybreak) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4174
			struct sk_buff *new_skb =
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4175
			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4176
			if (new_skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4177
				skb_reserve(new_skb, NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4178
				skb_copy_to_linear_data_offset(new_skb,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4179
							       -NET_IP_ALIGN,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4180
							       (skb->data -
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4181
							        NET_IP_ALIGN),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4182
							       (length +
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4183
							        NET_IP_ALIGN));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4184
				/* save the skb in buffer_info as good */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4185
				buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4186
				skb = new_skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4187
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4188
			/* else just continue with the old one */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4189
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4190
		/* end copybreak code */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4191
		skb_put(skb, length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4192
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4193
		/* Receive Checksum Offload */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4194
		e1000_rx_checksum(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4195
				  (u32)(status) |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4196
				  ((u32)(rx_desc->errors) << 24),
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4197
				  le16_to_cpu(rx_desc->csum), skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4198
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4199
		if (adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4200
			ecdev_receive(adapter->ecdev, skb->data, length);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4201
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4202
			// No need to detect link status as
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4203
			// long as frames are received: Reset watchdog.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4204
			adapter->ec_watchdog_jiffies = jiffies;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4205
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4206
			skb->protocol = eth_type_trans(skb, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4207
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4208
			if (unlikely(adapter->vlgrp &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4209
						(status & E1000_RXD_STAT_VP))) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4210
				vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4211
						le16_to_cpu(rx_desc->special));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4212
			} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4213
				netif_receive_skb(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4214
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4215
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4216
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4217
next_desc:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4218
		rx_desc->status = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4219
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4220
		/* return some buffers to hardware, one at a time is too slow */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4221
		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4222
			adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4223
			cleaned_count = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4224
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4225
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4226
		/* use prefetched values */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4227
		rx_desc = next_rxd;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4228
		buffer_info = next_buffer;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4229
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4230
	rx_ring->next_to_clean = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4231
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4232
	cleaned_count = E1000_DESC_UNUSED(rx_ring);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4233
	if (cleaned_count)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4234
		adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4235
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4236
	adapter->total_rx_packets += total_rx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4237
	adapter->total_rx_bytes += total_rx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4238
	adapter->net_stats.rx_bytes += total_rx_bytes;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4239
	adapter->net_stats.rx_packets += total_rx_packets;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4240
	return cleaned;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4241
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4242
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4243
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4244
 * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4245
 * @adapter: address of board private structure
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4246
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4247
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4248
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4249
				   struct e1000_rx_ring *rx_ring,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4250
				   int cleaned_count)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4251
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4252
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4253
	struct net_device *netdev = adapter->netdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4254
	struct pci_dev *pdev = adapter->pdev;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4255
	struct e1000_rx_desc *rx_desc;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4256
	struct e1000_buffer *buffer_info;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4257
	struct sk_buff *skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4258
	unsigned int i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4259
	unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4260
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4261
	i = rx_ring->next_to_use;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4262
	buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4263
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4264
	while (cleaned_count--) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4265
		skb = buffer_info->skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4266
		if (skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4267
			skb_trim(skb, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4268
			goto map_skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4269
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4270
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4271
		skb = netdev_alloc_skb(netdev, bufsz);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4272
		if (unlikely(!skb)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4273
			/* Better luck next round */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4274
			adapter->alloc_rx_buff_failed++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4275
			break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4276
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4277
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4278
		/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4279
		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4280
			struct sk_buff *oldskb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4281
			DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4282
					     "at %p\n", bufsz, skb->data);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4283
			/* Try again, without freeing the previous */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4284
			skb = netdev_alloc_skb(netdev, bufsz);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4285
			/* Failed allocation, critical failure */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4286
			if (!skb) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4287
				dev_kfree_skb(oldskb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4288
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4289
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4290
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4291
			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4292
				/* give up */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4293
				dev_kfree_skb(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4294
				dev_kfree_skb(oldskb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4295
				break; /* while !buffer_info->skb */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4296
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4297
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4298
			/* Use new allocation */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4299
			dev_kfree_skb(oldskb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4300
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4301
		/* Make buffer alignment 2 beyond a 16 byte boundary
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4302
		 * this will result in a 16 byte aligned IP header after
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4303
		 * the 14 byte MAC header is removed
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4304
		 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4305
		skb_reserve(skb, NET_IP_ALIGN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4306
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4307
		buffer_info->skb = skb;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4308
		buffer_info->length = adapter->rx_buffer_len;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4309
map_skb:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4310
		buffer_info->dma = pci_map_single(pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4311
						  skb->data,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4312
						  adapter->rx_buffer_len,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4313
						  PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4314
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4315
		/* Fix for errata 23, can't cross 64kB boundary */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4316
		if (!e1000_check_64k_bound(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4317
					(void *)(unsigned long)buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4318
					adapter->rx_buffer_len)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4319
			DPRINTK(RX_ERR, ERR,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4320
				"dma align check failed: %u bytes at %p\n",
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4321
				adapter->rx_buffer_len,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4322
				(void *)(unsigned long)buffer_info->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4323
			if (!adapter->ecdev) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4324
				dev_kfree_skb(skb);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4325
				buffer_info->skb = NULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4326
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4327
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4328
			pci_unmap_single(pdev, buffer_info->dma,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4329
					 adapter->rx_buffer_len,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4330
					 PCI_DMA_FROMDEVICE);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4331
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4332
			break; /* while !buffer_info->skb */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4333
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4334
		rx_desc = E1000_RX_DESC(*rx_ring, i);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4335
		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4336
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4337
		if (unlikely(++i == rx_ring->count))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4338
			i = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4339
		buffer_info = &rx_ring->buffer_info[i];
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4340
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4341
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4342
	if (likely(rx_ring->next_to_use != i)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4343
		rx_ring->next_to_use = i;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4344
		if (unlikely(i-- == 0))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4345
			i = (rx_ring->count - 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4346
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4347
		/* Force memory writes to complete before letting h/w
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4348
		 * know there are new descriptors to fetch.  (Only
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4349
		 * applicable for weak-ordered memory model archs,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4350
		 * such as IA-64). */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4351
		wmb();
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4352
		writel(i, hw->hw_addr + rx_ring->rdt);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4353
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4354
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4355
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4356
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4357
 * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4358
 * @adapter:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4359
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4360
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4361
static void e1000_smartspeed(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4362
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4363
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4364
	u16 phy_status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4365
	u16 phy_ctrl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4366
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4367
	if ((hw->phy_type != e1000_phy_igp) || !hw->autoneg ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4368
	   !(hw->autoneg_advertised & ADVERTISE_1000_FULL))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4369
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4370
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4371
	if (adapter->smartspeed == 0) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4372
		/* If Master/Slave config fault is asserted twice,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4373
		 * we assume back-to-back */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4374
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4375
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4376
		e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_status);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4377
		if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4378
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4379
		if (phy_ctrl & CR_1000T_MS_ENABLE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4380
			phy_ctrl &= ~CR_1000T_MS_ENABLE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4381
			e1000_write_phy_reg(hw, PHY_1000T_CTRL,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4382
					    phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4383
			adapter->smartspeed++;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4384
			if (!e1000_phy_setup_autoneg(hw) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4385
			   !e1000_read_phy_reg(hw, PHY_CTRL,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4386
				   	       &phy_ctrl)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4387
				phy_ctrl |= (MII_CR_AUTO_NEG_EN |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4388
					     MII_CR_RESTART_AUTO_NEG);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4389
				e1000_write_phy_reg(hw, PHY_CTRL,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4390
						    phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4391
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4392
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4393
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4394
	} else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4395
		/* If still no link, perhaps using 2/3 pair cable */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4396
		e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4397
		phy_ctrl |= CR_1000T_MS_ENABLE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4398
		e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4399
		if (!e1000_phy_setup_autoneg(hw) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4400
		   !e1000_read_phy_reg(hw, PHY_CTRL, &phy_ctrl)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4401
			phy_ctrl |= (MII_CR_AUTO_NEG_EN |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4402
				     MII_CR_RESTART_AUTO_NEG);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4403
			e1000_write_phy_reg(hw, PHY_CTRL, phy_ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4404
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4405
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4406
	/* Restart process after E1000_SMARTSPEED_MAX iterations */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4407
	if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4408
		adapter->smartspeed = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4409
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4410
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4411
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4412
 * e1000_ioctl -
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4413
 * @netdev:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4414
 * @ifreq:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4415
 * @cmd:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4416
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4417
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4418
static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4419
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4420
	switch (cmd) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4421
	case SIOCGMIIPHY:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4422
	case SIOCGMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4423
	case SIOCSMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4424
		return e1000_mii_ioctl(netdev, ifr, cmd);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4425
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4426
		return -EOPNOTSUPP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4427
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4428
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4429
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4430
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4431
 * e1000_mii_ioctl -
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4432
 * @netdev:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4433
 * @ifreq:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4434
 * @cmd:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4435
 **/
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4436
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4437
static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4438
			   int cmd)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4439
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4440
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4441
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4442
	struct mii_ioctl_data *data = if_mii(ifr);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4443
	int retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4444
	u16 mii_reg;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4445
	u16 spddplx;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4446
	unsigned long flags;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4447
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4448
	if (hw->media_type != e1000_media_type_copper)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4449
		return -EOPNOTSUPP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4450
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4451
	switch (cmd) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4452
	case SIOCGMIIPHY:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4453
		data->phy_id = hw->phy_addr;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4454
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4455
	case SIOCGMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4456
		if (adapter->ecdev || !capable(CAP_NET_ADMIN))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4457
			return -EPERM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4458
		spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4459
		if (e1000_read_phy_reg(hw, data->reg_num & 0x1F,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4460
				   &data->val_out)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4461
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4462
			return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4463
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4464
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4465
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4466
	case SIOCSMIIREG:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4467
		if (adapter->ecdev || !capable(CAP_NET_ADMIN))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4468
			return -EPERM;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4469
		if (data->reg_num & ~(0x1F))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4470
			return -EFAULT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4471
		mii_reg = data->val_in;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4472
		spin_lock_irqsave(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4473
		if (e1000_write_phy_reg(hw, data->reg_num,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4474
					mii_reg)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4475
			spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4476
			return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4477
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4478
		spin_unlock_irqrestore(&adapter->stats_lock, flags);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4479
		if (hw->media_type == e1000_media_type_copper) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4480
			switch (data->reg_num) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4481
			case PHY_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4482
				if (mii_reg & MII_CR_POWER_DOWN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4483
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4484
				if (mii_reg & MII_CR_AUTO_NEG_EN) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4485
					hw->autoneg = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4486
					hw->autoneg_advertised = 0x2F;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4487
				} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4488
					if (mii_reg & 0x40)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4489
						spddplx = SPEED_1000;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4490
					else if (mii_reg & 0x2000)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4491
						spddplx = SPEED_100;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4492
					else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4493
						spddplx = SPEED_10;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4494
					spddplx += (mii_reg & 0x100)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4495
						   ? DUPLEX_FULL :
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4496
						   DUPLEX_HALF;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4497
					retval = e1000_set_spd_dplx(adapter,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4498
								    spddplx);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4499
					if (retval)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4500
						return retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4501
				}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4502
				if (netif_running(adapter->netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4503
					e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4504
				else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4505
					e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4506
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4507
			case M88E1000_PHY_SPEC_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4508
			case M88E1000_EXT_PHY_SPEC_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4509
				if (e1000_phy_reset(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4510
					return -EIO;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4511
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4512
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4513
		} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4514
			switch (data->reg_num) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4515
			case PHY_CTRL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4516
				if (mii_reg & MII_CR_POWER_DOWN)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4517
					break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4518
				if (netif_running(adapter->netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4519
					e1000_reinit_locked(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4520
				else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4521
					e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4522
				break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4523
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4524
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4525
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4526
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4527
		return -EOPNOTSUPP;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4528
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4529
	return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4530
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4531
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4532
void e1000_pci_set_mwi(struct e1000_hw *hw)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4533
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4534
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4535
	int ret_val = pci_set_mwi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4536
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4537
	if (ret_val)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4538
		DPRINTK(PROBE, ERR, "Error in setting MWI\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4539
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4540
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4541
void e1000_pci_clear_mwi(struct e1000_hw *hw)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4542
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4543
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4544
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4545
	pci_clear_mwi(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4546
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4547
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4548
int e1000_pcix_get_mmrbc(struct e1000_hw *hw)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4549
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4550
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4551
	return pcix_get_mmrbc(adapter->pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4552
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4553
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4554
void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4555
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4556
	struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4557
	pcix_set_mmrbc(adapter->pdev, mmrbc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4558
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4559
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4560
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4561
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4562
    struct e1000_adapter *adapter = hw->back;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4563
    u16 cap_offset;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4564
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4565
    cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4566
    if (!cap_offset)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4567
        return -E1000_ERR_CONFIG;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4568
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4569
    pci_read_config_word(adapter->pdev, cap_offset + reg, value);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4570
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4571
    return E1000_SUCCESS;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4572
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4573
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4574
void e1000_io_write(struct e1000_hw *hw, unsigned long port, u32 value)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4575
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4576
	outl(value, port);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4577
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4578
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4579
static void e1000_vlan_rx_register(struct net_device *netdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4580
				   struct vlan_group *grp)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4581
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4582
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4583
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4584
	u32 ctrl, rctl;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4585
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4586
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4587
		e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4588
	adapter->vlgrp = grp;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4589
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4590
	if (grp) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4591
		/* enable VLAN tag insert/strip */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4592
		ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4593
		ctrl |= E1000_CTRL_VME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4594
		ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4595
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4596
		if (adapter->hw.mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4597
			/* enable VLAN receive filtering */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4598
			rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4599
			rctl &= ~E1000_RCTL_CFIEN;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4600
			ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4601
			e1000_update_mng_vlan(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4602
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4603
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4604
		/* disable VLAN tag insert/strip */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4605
		ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4606
		ctrl &= ~E1000_CTRL_VME;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4607
		ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4608
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4609
		if (adapter->hw.mac_type != e1000_ich8lan) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4610
			if (adapter->mng_vlan_id !=
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4611
			    (u16)E1000_MNG_VLAN_NONE) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4612
				e1000_vlan_rx_kill_vid(netdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4613
				                       adapter->mng_vlan_id);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4614
				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4615
			}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4616
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4617
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4618
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4619
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4620
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4621
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4622
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4623
static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4624
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4625
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4626
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4627
	u32 vfta, index;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4628
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4629
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4630
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4631
	    (vid == adapter->mng_vlan_id))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4632
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4633
	/* add VID to filter table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4634
	index = (vid >> 5) & 0x7F;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4635
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4636
	vfta |= (1 << (vid & 0x1F));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4637
	e1000_write_vfta(hw, index, vfta);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4638
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4639
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4640
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4641
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4642
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4643
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4644
	u32 vfta, index;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4645
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4646
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4647
		e1000_irq_disable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4648
	vlan_group_set_device(adapter->vlgrp, vid, NULL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4649
	if (!test_bit(__E1000_DOWN, &adapter->flags))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4650
		e1000_irq_enable(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4651
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4652
	if ((hw->mng_cookie.status &
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4653
	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4654
	    (vid == adapter->mng_vlan_id)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4655
		/* release control to f/w */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4656
		e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4657
		return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4658
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4659
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4660
	/* remove VID from filter table */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4661
	index = (vid >> 5) & 0x7F;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4662
	vfta = E1000_READ_REG_ARRAY(hw, VFTA, index);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4663
	vfta &= ~(1 << (vid & 0x1F));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4664
	e1000_write_vfta(hw, index, vfta);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4665
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4666
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4667
static void e1000_restore_vlan(struct e1000_adapter *adapter)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4668
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4669
	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4670
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4671
	if (adapter->vlgrp) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4672
		u16 vid;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4673
		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4674
			if (!vlan_group_get_device(adapter->vlgrp, vid))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4675
				continue;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4676
			e1000_vlan_rx_add_vid(adapter->netdev, vid);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4677
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4678
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4679
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4680
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4681
int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4682
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4683
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4684
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4685
	hw->autoneg = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4686
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4687
	/* Fiber NICs only allow 1000 gbps Full duplex */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4688
	if ((hw->media_type == e1000_media_type_fiber) &&
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4689
		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4690
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4691
		return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4692
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4693
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4694
	switch (spddplx) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4695
	case SPEED_10 + DUPLEX_HALF:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4696
		hw->forced_speed_duplex = e1000_10_half;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4697
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4698
	case SPEED_10 + DUPLEX_FULL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4699
		hw->forced_speed_duplex = e1000_10_full;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4700
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4701
	case SPEED_100 + DUPLEX_HALF:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4702
		hw->forced_speed_duplex = e1000_100_half;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4703
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4704
	case SPEED_100 + DUPLEX_FULL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4705
		hw->forced_speed_duplex = e1000_100_full;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4706
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4707
	case SPEED_1000 + DUPLEX_FULL:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4708
		hw->autoneg = 1;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4709
		hw->autoneg_advertised = ADVERTISE_1000_FULL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4710
		break;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4711
	case SPEED_1000 + DUPLEX_HALF: /* not supported */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4712
	default:
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4713
		DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4714
		return -EINVAL;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4715
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4716
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4717
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4718
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4719
static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4720
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4721
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4722
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4723
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4724
	u32 ctrl, ctrl_ext, rctl, status;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4725
	u32 wufc = adapter->wol;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4726
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4727
	int retval = 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4728
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4729
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4730
	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4731
		return -EBUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4732
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4733
	netif_device_detach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4734
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4735
	if (netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4736
		WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4737
		e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4738
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4739
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4740
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4741
	retval = pci_save_state(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4742
	if (retval)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4743
		return retval;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4744
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4745
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4746
	status = er32(STATUS);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4747
	if (status & E1000_STATUS_LU)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4748
		wufc &= ~E1000_WUFC_LNKC;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4749
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4750
	if (wufc) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4751
		e1000_setup_rctl(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4752
		e1000_set_rx_mode(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4753
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4754
		/* turn on all-multi mode if wake on multicast is enabled */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4755
		if (wufc & E1000_WUFC_MC) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4756
			rctl = er32(RCTL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4757
			rctl |= E1000_RCTL_MPE;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4758
			ew32(RCTL, rctl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4759
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4760
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4761
		if (hw->mac_type >= e1000_82540) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4762
			ctrl = er32(CTRL);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4763
			/* advertise wake from D3Cold */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4764
			#define E1000_CTRL_ADVD3WUC 0x00100000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4765
			/* phy power management enable */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4766
			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4767
			ctrl |= E1000_CTRL_ADVD3WUC |
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4768
				E1000_CTRL_EN_PHY_PWR_MGMT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4769
			ew32(CTRL, ctrl);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4770
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4771
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4772
		if (hw->media_type == e1000_media_type_fiber ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4773
		   hw->media_type == e1000_media_type_internal_serdes) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4774
			/* keep the laser running in D3 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4775
			ctrl_ext = er32(CTRL_EXT);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4776
			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4777
			ew32(CTRL_EXT, ctrl_ext);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4778
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4779
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4780
		/* Allow time for pending master requests to run */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4781
		e1000_disable_pciex_master(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4782
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4783
		ew32(WUC, E1000_WUC_PME_EN);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4784
		ew32(WUFC, wufc);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4785
		pci_enable_wake(pdev, PCI_D3hot, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4786
		pci_enable_wake(pdev, PCI_D3cold, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4787
	} else {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4788
		ew32(WUC, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4789
		ew32(WUFC, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4790
		pci_enable_wake(pdev, PCI_D3hot, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4791
		pci_enable_wake(pdev, PCI_D3cold, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4792
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4793
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4794
	e1000_release_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4795
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4796
	/* make sure adapter isn't asleep if manageability is enabled */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4797
	if (adapter->en_mng_pt) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4798
		pci_enable_wake(pdev, PCI_D3hot, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4799
		pci_enable_wake(pdev, PCI_D3cold, 1);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4800
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4801
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4802
	if (hw->phy_type == e1000_phy_igp_3)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4803
		e1000_phy_powerdown_workaround(hw);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4804
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4805
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4806
		e1000_free_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4807
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4808
	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4809
	 * would have already happened in close and is redundant. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4810
	e1000_release_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4811
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4812
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4813
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4814
	pci_set_power_state(pdev, pci_choose_state(pdev, state));
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4815
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4816
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4817
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4818
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4819
#ifdef CONFIG_PM
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4820
static int e1000_resume(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4821
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4822
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4823
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4824
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4825
	u32 err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4826
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4827
	if (adapter->ecdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4828
		return -EBUSY;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4829
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4830
	pci_set_power_state(pdev, PCI_D0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4831
	pci_restore_state(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4832
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4833
	if (adapter->need_ioport)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4834
		err = pci_enable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4835
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4836
		err = pci_enable_device_mem(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4837
	if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4838
		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4839
		return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4840
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4841
	pci_set_master(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4842
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4843
	pci_enable_wake(pdev, PCI_D3hot, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4844
	pci_enable_wake(pdev, PCI_D3cold, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4845
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4846
	if (netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4847
		err = e1000_request_irq(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4848
		if (err)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4849
			return err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4850
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4851
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4852
	e1000_power_up_phy(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4853
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4854
	ew32(WUS, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4855
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4856
	e1000_init_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4857
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4858
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4859
		e1000_up(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4860
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4861
	if (!adapter->ecdev) netif_device_attach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4862
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4863
	/* If the controller is 82573 and f/w is AMT, do not set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4864
	 * DRV_LOAD until the interface is up.  For all other cases,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4865
	 * let the f/w know that the h/w is now under the control
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4866
	 * of the driver. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4867
	if (hw->mac_type != e1000_82573 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4868
	    !e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4869
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4870
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4871
	return 0;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4872
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4873
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4874
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4875
static void e1000_shutdown(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4876
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4877
	e1000_suspend(pdev, PMSG_SUSPEND);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4878
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4879
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4880
#ifdef CONFIG_NET_POLL_CONTROLLER
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4881
/*
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4882
 * Polling 'interrupt' - used by things like netconsole to send skbs
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4883
 * without having to re-enable interrupts. It's not called while
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4884
 * the interrupt routine is executing.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4885
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4886
static void e1000_netpoll(struct net_device *netdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4887
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4888
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4889
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4890
	disable_irq(adapter->pdev->irq);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4891
	e1000_intr(adapter->pdev->irq, netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4892
	enable_irq(adapter->pdev->irq);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4893
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4894
#endif
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4895
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4896
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4897
 * e1000_io_error_detected - called when PCI error is detected
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4898
 * @pdev: Pointer to PCI device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4899
 * @state: The current pci conneection state
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4900
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4901
 * This function is called after a PCI bus error affecting
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4902
 * this device has been detected.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4903
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4904
static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4905
						pci_channel_state_t state)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4906
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4907
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4908
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4909
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4910
	netif_device_detach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4911
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4912
	if (netif_running(netdev))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4913
		e1000_down(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4914
	pci_disable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4915
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4916
	/* Request a slot slot reset. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4917
	return PCI_ERS_RESULT_NEED_RESET;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4918
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4919
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4920
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4921
 * e1000_io_slot_reset - called after the pci bus has been reset.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4922
 * @pdev: Pointer to PCI device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4923
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4924
 * Restart the card from scratch, as if from a cold-boot. Implementation
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4925
 * resembles the first-half of the e1000_resume routine.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4926
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4927
static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4928
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4929
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4930
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4931
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4932
	int err;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4933
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4934
	if (adapter->need_ioport)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4935
		err = pci_enable_device(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4936
	else
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4937
		err = pci_enable_device_mem(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4938
	if (err) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4939
		printk(KERN_ERR "e1000: Cannot re-enable PCI device after reset.\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4940
		return PCI_ERS_RESULT_DISCONNECT;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4941
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4942
	pci_set_master(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4943
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4944
	pci_enable_wake(pdev, PCI_D3hot, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4945
	pci_enable_wake(pdev, PCI_D3cold, 0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4946
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4947
	e1000_reset(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4948
	ew32(WUS, ~0);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4949
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4950
	return PCI_ERS_RESULT_RECOVERED;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4951
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4952
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4953
/**
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4954
 * e1000_io_resume - called when traffic can start flowing again.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4955
 * @pdev: Pointer to PCI device
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4956
 *
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4957
 * This callback is called when the error recovery driver tells us that
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4958
 * its OK to resume normal operation. Implementation resembles the
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4959
 * second-half of the e1000_resume routine.
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4960
 */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4961
static void e1000_io_resume(struct pci_dev *pdev)
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4962
{
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4963
	struct net_device *netdev = pci_get_drvdata(pdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4964
	struct e1000_adapter *adapter = netdev_priv(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4965
	struct e1000_hw *hw = &adapter->hw;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4966
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4967
	e1000_init_manageability(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4968
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4969
	if (netif_running(netdev)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4970
		if (e1000_up(adapter)) {
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4971
			printk("e1000: can't bring device back up after reset\n");
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4972
			return;
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4973
		}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4974
	}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4975
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4976
	netif_device_attach(netdev);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4977
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4978
	/* If the controller is 82573 and f/w is AMT, do not set
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4979
	 * DRV_LOAD until the interface is up.  For all other cases,
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4980
	 * let the f/w know that the h/w is now under the control
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4981
	 * of the driver. */
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4982
	if (hw->mac_type != e1000_82573 ||
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4983
	    !e1000_check_mng_mode(hw))
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4984
		e1000_get_hw_control(adapter);
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4985
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4986
}
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4987
4adb56c4198d Add e1000 for 2.6.29
Andreas Stewering-Bone <ab@igh-essen.com>
parents:
diff changeset
  4988
/* e1000_main.c */